Changeset 85894 in vbox for trunk/src/VBox/Runtime
- Timestamp:
- Aug 26, 2020 8:50:52 PM (4 years ago)
- Location:
- trunk/src/VBox/Runtime
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/dvm/dvm.cpp
r85890 r85894 627 627 } 628 628 629 RTDECL(int) RTDvmMapQueryTableLocations(RTDVM hVolMgr, uint32_t fFlags, 630 PRTDVMTABLELOCATION paLocations, size_t cLocations, size_t *pcActual) 631 { 632 PRTDVMINTERNAL pThis = hVolMgr; 633 634 /* 635 * Input validation. 636 */ 637 if (cLocations) 638 { 639 AssertPtrReturn(paLocations, VERR_INVALID_POINTER); 640 if (pcActual) 641 { 642 AssertPtrReturn(pcActual, VERR_INVALID_POINTER); 643 *pcActual = 0; 644 } 645 } 646 else 647 { 648 AssertPtrReturn(pcActual, VERR_INVALID_POINTER); 649 *pcActual = 0; 650 } 651 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 652 AssertReturn(pThis->u32Magic == RTDVM_MAGIC, VERR_INVALID_HANDLE); 653 AssertReturn(!(fFlags & ~RTDVMMAPQTABLOC_F_VALID_MASK), VERR_INVALID_FLAGS); 654 655 /* 656 * Pass it down to the format backend. 657 */ 658 return pThis->pDvmFmtOps->pfnQueryTableLocations(pThis->hVolMgrFmt, fFlags, paLocations, cLocations, pcActual); 659 } 660 629 661 RTDECL(uint32_t) RTDvmVolumeRetain(RTDVMVOLUME hVol) 630 662 { -
trunk/src/VBox/Runtime/common/dvm/dvmbsdlabel.cpp
r85887 r85894 442 442 } 443 443 444 /** @copydoc RTDVMFMTOPS::pfnQueryTableLocations */ 445 static DECLCALLBACK(int) rtDvmFmtBsdLblQueryTableLocations(RTDVMFMT hVolMgrFmt, uint32_t fFlags, PRTDVMTABLELOCATION paLocations, 446 size_t cLocations, size_t *pcActual) 447 { 448 PRTDVMFMTINTERNAL pThis = hVolMgrFmt; 449 450 /* 451 * The MBR if requested. 452 */ 453 int rc = VINF_SUCCESS; 454 size_t iLoc = 0; 455 if (fFlags & RTDVMMAPQTABLOC_F_INCLUDE_LEGACY) 456 { 457 if (cLocations > 0) 458 { 459 paLocations[iLoc].off = 0; 460 paLocations[iLoc].cb = RTDVM_BSDLBL_LBA2BYTE(1, pThis->pDisk); 461 paLocations[iLoc].cbPadding = 0; 462 } 463 else 464 rc = VERR_BUFFER_OVERFLOW; 465 iLoc++; 466 } 467 468 /* 469 * The BSD lable. 470 */ 471 if (cLocations > iLoc) 472 { 473 paLocations[iLoc].off = RTDVM_BSDLBL_LBA2BYTE(1, pThis->pDisk); 474 paLocations[iLoc].cb = (sizeof(BsdLabel) + pThis->pDisk->cbSector - 1) / pThis->pDisk->cbSector * pThis->pDisk->cbSector; 475 476 uint32_t offFirstSector = pThis->pDisk->cbDisk / pThis->pDisk->cbSector; 477 for (unsigned i = 0; i < pThis->DiskLabel.cPartitions; i++) 478 if ( pThis->DiskLabel.aPartitions[i].cSectors 479 && pThis->DiskLabel.aPartitions[i].offSectorStart < offFirstSector) 480 offFirstSector = pThis->DiskLabel.aPartitions[i].offSectorStart; 481 482 uint64_t offEnd = paLocations[iLoc].off + paLocations[iLoc].cb; 483 paLocations[iLoc].cbPadding = (uint64_t)offFirstSector * pThis->DiskLabel.cbSector; 484 if (paLocations[iLoc].cbPadding > offEnd) 485 paLocations[iLoc].cbPadding -= offEnd; 486 else 487 AssertFailedStmt(paLocations[iLoc].cbPadding = 0); 488 } 489 else 490 rc = VERR_BUFFER_OVERFLOW; 491 iLoc++; 492 493 /* 494 * Return values. 495 */ 496 if (pcActual) 497 *pcActual = iLoc; 498 else if (cLocations != iLoc && RT_SUCCESS(rc)) 499 { 500 RT_BZERO(&paLocations[iLoc], (cLocations - iLoc) * sizeof(paLocations[0])); 501 rc = VERR_BUFFER_UNDERFLOW; 502 } 503 return rc; 504 } 505 444 506 static DECLCALLBACK(void) rtDvmFmtBsdLblVolumeClose(RTDVMVOLUMEFMT hVolFmt) 445 507 { … … 607 669 /* pfnQueryNextVolume */ 608 670 rtDvmFmtBsdLblQueryNextVolume, 671 /* pfnQueryTableLocations */ 672 rtDvmFmtBsdLblQueryTableLocations, 609 673 /* pfnVolumeClose */ 610 674 rtDvmFmtBsdLblVolumeClose, -
trunk/src/VBox/Runtime/common/dvm/dvmgpt.cpp
r85887 r85894 463 463 } 464 464 465 /** @copydoc RTDVMFMTOPS::pfnQueryTableLocations */ 466 static DECLCALLBACK(int) rtDvmFmtGptQueryTableLocations(RTDVMFMT hVolMgrFmt, uint32_t fFlags, PRTDVMTABLELOCATION paLocations, 467 size_t cLocations, size_t *pcActual) 468 { 469 PRTDVMFMTINTERNAL pThis = hVolMgrFmt; 470 471 /* 472 * The MBR if requested. 473 */ 474 int rc = VINF_SUCCESS; 475 size_t iLoc = 0; 476 if (fFlags & RTDVMMAPQTABLOC_F_INCLUDE_LEGACY) 477 { 478 if (cLocations > 0) 479 { 480 paLocations[iLoc].off = 0; 481 paLocations[iLoc].cb = RTDVM_GPT_LBA2BYTE(1, pThis->pDisk); 482 paLocations[iLoc].cbPadding = 0; 483 } 484 else 485 rc = VERR_BUFFER_OVERFLOW; 486 iLoc++; 487 } 488 489 /* 490 * The GPT. 491 */ 492 if (cLocations > iLoc) 493 { 494 uint64_t const offEnd = (pThis->HdrRev1.cPartitionEntries * pThis->HdrRev1.cbPartitionEntry + pThis->pDisk->cbSector - 1) 495 / pThis->pDisk->cbSector 496 * pThis->pDisk->cbSector; 497 paLocations[iLoc].off = RTDVM_GPT_LBA2BYTE(1, pThis->pDisk); 498 paLocations[iLoc].cb = offEnd - paLocations[iLoc].off; 499 500 uint64_t uLbaFirstPart = pThis->pDisk->cbDisk / pThis->pDisk->cbSector; 501 for (unsigned i = 0; i < pThis->HdrRev1.cPartitionEntries; i++) 502 if ( pThis->paGptEntries[i].u64LbaFirst < uLbaFirstPart 503 && !RTUuidIsNull(&pThis->paGptEntries[i].UuidType)) 504 uLbaFirstPart = pThis->paGptEntries[i].u64LbaFirst; 505 506 paLocations[iLoc].cbPadding = RTDVM_GPT_LBA2BYTE(uLbaFirstPart, pThis->pDisk); 507 if (paLocations[iLoc].cbPadding > offEnd) 508 paLocations[iLoc].cbPadding -= offEnd; 509 else 510 AssertFailedStmt(paLocations[iLoc].cbPadding = 0); 511 } 512 else 513 rc = VERR_BUFFER_OVERFLOW; 514 iLoc++; 515 516 /* 517 * Return values. 518 */ 519 if (pcActual) 520 *pcActual = iLoc; 521 else if (cLocations != iLoc && RT_SUCCESS(rc)) 522 { 523 RT_BZERO(&paLocations[iLoc], (cLocations - iLoc) * sizeof(paLocations[0])); 524 rc = VERR_BUFFER_UNDERFLOW; 525 } 526 return rc; 527 } 528 465 529 static DECLCALLBACK(void) rtDvmFmtGptVolumeClose(RTDVMVOLUMEFMT hVolFmt) 466 530 { … … 650 714 /* pfnQueryNextVolume */ 651 715 rtDvmFmtGptQueryNextVolume, 716 /* pfnQueryTableLocations */ 717 rtDvmFmtGptQueryTableLocations, 652 718 /* pfnVolumeClose */ 653 719 rtDvmFmtGptVolumeClose, -
trunk/src/VBox/Runtime/common/dvm/dvmmbr.cpp
r85887 r85894 732 732 } 733 733 734 /** 735 * Helper for rtDvmFmtMbrQueryTableLocations that calculates the padding and/or 736 * free space at @a off. 737 * 738 * Because nothing need to be sorted by start offset, we have to traverse all 739 * partition tables to determine this. 740 */ 741 static uint64_t rtDvmFmtMbrCalcTablePadding(PRTDVMFMTINTERNAL pThis, uint64_t off) 742 { 743 uint64_t offNext = pThis->pDisk->cbDisk; 744 for (unsigned i = 0; i < 4; i++) 745 { 746 /* Check this primary entry */ 747 uint64_t offCur = pThis->Primary.aEntries[i].offPart; 748 if (offCur >= off && offCur < offNext && pThis->Primary.aEntries[i].bType != 0) 749 offNext = offCur; 750 751 /* If it's an extended partition, check the chained ones too. */ 752 for (PRTDVMMBRSECTOR pCur = pThis->Primary.aEntries[i].pChain; 753 pCur != NULL; 754 pCur->idxExtended != UINT8_MAX ? pCur->aEntries[pCur->idxExtended].pChain : NULL) 755 { 756 for (unsigned j = 0; j < 4; j++) 757 { 758 offCur = pCur->aEntries[j].offPart; 759 if (offCur >= off && offCur < offNext && pCur->aEntries[j].bType != 0) 760 offNext = offCur; 761 } 762 } 763 } 764 Assert(offNext >= off); 765 return offNext - off; 766 } 767 768 /** @copydoc RTDVMFMTOPS::pfnQueryTableLocations */ 769 static DECLCALLBACK(int) rtDvmFmtMbrQueryTableLocations(RTDVMFMT hVolMgrFmt, uint32_t fFlags, PRTDVMTABLELOCATION paLocations, 770 size_t cLocations, size_t *pcActual) 771 { 772 PRTDVMFMTINTERNAL pThis = hVolMgrFmt; 773 RT_NOREF(fFlags); 774 775 /* 776 * The MBR. 777 */ 778 int rc = VINF_SUCCESS; 779 size_t iLoc = 0; 780 if (cLocations > 0) 781 { 782 paLocations[iLoc].off = pThis->Primary.offOnDisk; 783 paLocations[iLoc].cb = pThis->cbSector; 784 paLocations[iLoc].cbPadding = rtDvmFmtMbrCalcTablePadding(pThis, 0 + pThis->cbSector); 785 } 786 else 787 rc = VERR_BUFFER_OVERFLOW; 788 iLoc++; 789 790 /* 791 * Now do the extended partitions. 792 * 793 * Remember, we only support multiple in the primary MBR, only the first 794 * one is honored in the chained ones. 795 */ 796 for (unsigned i = 0; i < 4; i++) 797 { 798 for (PRTDVMMBRSECTOR pCur = pThis->Primary.aEntries[i].pChain; 799 pCur != NULL; 800 pCur->idxExtended != UINT8_MAX ? pCur->aEntries[pCur->idxExtended].pChain : NULL) 801 { 802 if (cLocations > iLoc) 803 { 804 paLocations[iLoc].off = pCur->offOnDisk; 805 paLocations[iLoc].cb = pThis->cbSector; 806 paLocations[iLoc].cbPadding = rtDvmFmtMbrCalcTablePadding(pThis, pCur->offOnDisk + pThis->cbSector); 807 } 808 else 809 rc = VERR_BUFFER_OVERFLOW; 810 iLoc++; 811 } 812 } 813 814 /* 815 * Return values. 816 */ 817 if (pcActual) 818 *pcActual = iLoc; 819 else if (cLocations != iLoc && RT_SUCCESS(rc)) 820 { 821 RT_BZERO(&paLocations[iLoc], (cLocations - iLoc) * sizeof(paLocations[0])); 822 rc = VERR_BUFFER_UNDERFLOW; 823 } 824 return rc; 825 } 826 734 827 static DECLCALLBACK(void) rtDvmFmtMbrVolumeClose(RTDVMVOLUMEFMT hVolFmt) 735 828 { … … 937 1030 /* pfnQueryNextVolume */ 938 1031 rtDvmFmtMbrQueryNextVolume, 1032 /* pfnQueryTableLocations */ 1033 rtDvmFmtMbrQueryTableLocations, 939 1034 /* pfnVolumeClose */ 940 1035 rtDvmFmtMbrVolumeClose, -
trunk/src/VBox/Runtime/include/internal/dvm.h
r85887 r85894 185 185 186 186 /** 187 * Query the partition table locations. 188 * 189 * @returns IPRT status code. 190 * @retval VERR_BUFFER_OVERFLOW if the table is too small, @a *pcActual will be 191 * set to the required size. 192 * @retval VERR_BUFFER_UNDERFLOW if the table is too big and @a pcActual is 193 * NULL. 194 * @param hVolMgrFmt The format specific volume manager handle. 195 * @param fFlags Flags, see RTDVMMAPQTABLOC_F_XXX. 196 * @param paLocations Where to return the info. Ignored if @a cLocations 197 * is zero, then only @a pcActual matters. 198 * @param cLocations The size of @a paLocations in items. 199 * @param pcActual Where to return the actual number of locations, or 200 * on VERR_BUFFER_OVERFLOW the necessary table size. 201 * Optional, when not specified the cLocations value 202 * must match exactly or it fails with 203 * VERR_BUFFER_UNDERFLOW. 204 * @sa RTDvmMapQueryTableLocations 205 */ 206 DECLCALLBACKMEMBER(int, pfnQueryTableLocations,(RTDVMFMT hVolMgrFmt, uint32_t fFlags, PRTDVMTABLELOCATION paLocations, 207 size_t cLocations, size_t *pcActual)); 208 209 /** 187 210 * Closes a volume handle. 188 211 *
Note:
See TracChangeset
for help on using the changeset viewer.