VirtualBox

Changeset 85894 in vbox for trunk/src/VBox/Runtime


Ignore:
Timestamp:
Aug 26, 2020 8:50:52 PM (4 years ago)
Author:
vboxsync
Message:

IPRT/Dvm: Added RTDvmMapQueryTableLocations (for VMDK). Completely untested. bugref:9224

Location:
trunk/src/VBox/Runtime
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/common/dvm/dvm.cpp

    r85890 r85894  
    627627}
    628628
     629RTDECL(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
    629661RTDECL(uint32_t) RTDvmVolumeRetain(RTDVMVOLUME hVol)
    630662{
  • trunk/src/VBox/Runtime/common/dvm/dvmbsdlabel.cpp

    r85887 r85894  
    442442}
    443443
     444/** @copydoc RTDVMFMTOPS::pfnQueryTableLocations */
     445static 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
    444506static DECLCALLBACK(void) rtDvmFmtBsdLblVolumeClose(RTDVMVOLUMEFMT hVolFmt)
    445507{
     
    607669    /* pfnQueryNextVolume */
    608670    rtDvmFmtBsdLblQueryNextVolume,
     671    /* pfnQueryTableLocations */
     672    rtDvmFmtBsdLblQueryTableLocations,
    609673    /* pfnVolumeClose */
    610674    rtDvmFmtBsdLblVolumeClose,
  • trunk/src/VBox/Runtime/common/dvm/dvmgpt.cpp

    r85887 r85894  
    463463}
    464464
     465/** @copydoc RTDVMFMTOPS::pfnQueryTableLocations */
     466static 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
    465529static DECLCALLBACK(void) rtDvmFmtGptVolumeClose(RTDVMVOLUMEFMT hVolFmt)
    466530{
     
    650714    /* pfnQueryNextVolume */
    651715    rtDvmFmtGptQueryNextVolume,
     716    /* pfnQueryTableLocations */
     717    rtDvmFmtGptQueryTableLocations,
    652718    /* pfnVolumeClose */
    653719    rtDvmFmtGptVolumeClose,
  • trunk/src/VBox/Runtime/common/dvm/dvmmbr.cpp

    r85887 r85894  
    732732}
    733733
     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 */
     741static 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 */
     769static 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
    734827static DECLCALLBACK(void) rtDvmFmtMbrVolumeClose(RTDVMVOLUMEFMT hVolFmt)
    735828{
     
    9371030    /* pfnQueryNextVolume */
    9381031    rtDvmFmtMbrQueryNextVolume,
     1032    /* pfnQueryTableLocations */
     1033    rtDvmFmtMbrQueryTableLocations,
    9391034    /* pfnVolumeClose */
    9401035    rtDvmFmtMbrVolumeClose,
  • trunk/src/VBox/Runtime/include/internal/dvm.h

    r85887 r85894  
    185185
    186186    /**
     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    /**
    187210     * Closes a volume handle.
    188211     *
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette