VirtualBox

Ignore:
Timestamp:
Nov 7, 2017 6:59:38 PM (7 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
118969
Message:

iprt/dvm: Some API adjusting to VFS - work in progress.

Location:
trunk/src/VBox/Runtime/common/dvm
Files:
4 edited

Legend:

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

    r69111 r69609  
    101101 * Supported volume formats.
    102102 */
    103 static PCRTDVMFMTOPS g_aDvmFmts[] =
     103static PCRTDVMFMTOPS const g_aDvmFmts[] =
    104104{
    105105    &g_rtDvmFmtMbr,
     
    113113 * This is indexed by RTDVMVOLTYPE.
    114114 */
    115 static const char * g_apcszDvmVolTypes[] =
     115static const char * const g_apszDvmVolTypes[] =
    116116{
    117117    "Invalid",
     
    130130    "Solaris"
    131131};
     132AssertCompile(RT_ELEMENTS(g_apszDvmVolTypes) == RTDVMVOLTYPE_END);
     133
    132134
    133135/**
     
    139141 * @param   phVol    Where to store the generic volume handle on success.
    140142 */
    141 static int rtDvmVolumeCreate(PRTDVMINTERNAL pThis, RTDVMVOLUMEFMT hVolFmt,
    142                              PRTDVMVOLUME phVol)
    143 {
    144     int rc = VINF_SUCCESS;
    145     PRTDVMVOLUMEINTERNAL pVol = NULL;
    146 
    147     pVol = (PRTDVMVOLUMEINTERNAL)RTMemAllocZ(sizeof(RTDVMVOLUMEINTERNAL));
     143static int rtDvmVolumeCreate(PRTDVMINTERNAL pThis, RTDVMVOLUMEFMT hVolFmt, PRTDVMVOLUME phVol)
     144{
     145    PRTDVMVOLUMEINTERNAL pVol = (PRTDVMVOLUMEINTERNAL)RTMemAllocZ(sizeof(RTDVMVOLUMEINTERNAL));
    148146    if (pVol)
    149147    {
     
    154152
    155153        *phVol = pVol;
    156     }
    157     else
    158         rc = VERR_NO_MEMORY;
    159 
    160     return rc;
     154        return VINF_SUCCESS;
     155    }
     156    return VERR_NO_MEMORY;
    161157}
    162158
     
    184180}
    185181
    186 RTDECL(int) RTDvmCreate(PRTDVM phVolMgr, PFNDVMREAD pfnRead,
    187                         PFNDVMWRITE pfnWrite, uint64_t cbDisk,
    188                         uint64_t cbSector, uint32_t fFlags, void *pvUser)
    189 {
    190     int rc = VINF_SUCCESS;
    191     PRTDVMINTERNAL pThis;
    192 
    193     AssertMsgReturn(!(fFlags & ~DVM_FLAGS_MASK),
    194                     ("Invalid flags given %#x\n", fFlags),
    195                     VERR_INVALID_PARAMETER);
    196 
    197     pThis = (PRTDVMINTERNAL)RTMemAllocZ(sizeof(RTDVMINTERNAL));
    198     if (pThis)
    199     {
    200         pThis->u32Magic         = RTDVM_MAGIC;
    201         pThis->DvmDisk.cbDisk   = cbDisk;
    202         pThis->DvmDisk.cbSector = cbSector;
    203         pThis->DvmDisk.pvUser   = pvUser;
    204         pThis->DvmDisk.pfnRead  = pfnRead;
    205         pThis->DvmDisk.pfnWrite = pfnWrite;
    206         pThis->pDvmFmtOps       = NULL;
    207         pThis->hVolMgrFmt       = NIL_RTDVMFMT;
    208         pThis->fFlags           = fFlags;
    209         pThis->cRefs            = 1;
    210         RTListInit(&pThis->VolumeList);
    211         *phVolMgr = pThis;
    212     }
    213     else
     182
     183RTDECL(int) RTDvmCreate(PRTDVM phVolMgr, RTVFSFILE hVfsFile, uint32_t cbSector, uint32_t fFlags)
     184{
     185    AssertMsgReturn(!(fFlags & ~DVM_FLAGS_VALID_MASK), ("Invalid flags given %#x\n", fFlags), VERR_INVALID_FLAGS);
     186    uint32_t cRefs = RTVfsFileRetain(hVfsFile);
     187    AssertReturn(cRefs != UINT32_MAX, VERR_INVALID_HANDLE);
     188
     189    uint64_t cbDisk;
     190    int rc = RTVfsFileGetSize(hVfsFile, &cbDisk);
     191    if (RT_SUCCESS(rc))
     192    {
     193        PRTDVMINTERNAL pThis = (PRTDVMINTERNAL)RTMemAllocZ(sizeof(RTDVMINTERNAL));
     194        if (pThis)
     195        {
     196            pThis->u32Magic         = RTDVM_MAGIC;
     197            pThis->DvmDisk.cbDisk   = cbDisk;
     198            pThis->DvmDisk.cbSector = cbSector;
     199            pThis->DvmDisk.hVfsFile = hVfsFile;
     200
     201            pThis->pDvmFmtOps       = NULL;
     202            pThis->hVolMgrFmt       = NIL_RTDVMFMT;
     203            pThis->fFlags           = fFlags;
     204            pThis->cRefs            = 1;
     205            RTListInit(&pThis->VolumeList);
     206
     207            *phVolMgr = pThis;
     208            return VINF_SUCCESS;
     209        }
    214210        rc = VERR_NO_MEMORY;
    215 
     211    }
     212    RTVfsFileRelease(hVfsFile);
    216213    return rc;
    217214}
     215
    218216
    219217RTDECL(uint32_t) RTDvmRetain(RTDVM hVolMgr)
     
    235233static void rtDvmDestroy(PRTDVMINTERNAL pThis)
    236234{
     235    pThis->u32Magic = RTDVM_MAGIC_DEAD;
     236
    237237    if (pThis->hVolMgrFmt != NIL_RTDVMFMT)
    238238    {
     
    242242        pThis->pDvmFmtOps->pfnClose(pThis->hVolMgrFmt);
    243243        pThis->hVolMgrFmt = NIL_RTDVMFMT;
    244     }
    245 
    246     pThis->DvmDisk.cbDisk   = 0;
    247     pThis->DvmDisk.pvUser   = NULL;
    248     pThis->DvmDisk.pfnRead  = NULL;
    249     pThis->DvmDisk.pfnWrite = NULL;
    250     pThis->u32Magic         = RTDVM_MAGIC_DEAD;
     244        pThis->pDvmFmtOps = NULL;
     245    }
     246
     247    pThis->DvmDisk.cbDisk = 0;
     248    pThis->DvmDisk.cbSector = 0;
     249    if (pThis->DvmDisk.hVfsFile != NIL_RTVFSFILE)
     250    {
     251        RTVfsFileRelease(pThis->DvmDisk.hVfsFile);
     252        pThis->DvmDisk.hVfsFile = NIL_RTVFSFILE;
     253    }
    251254    RTMemFree(pThis);
    252255}
     
    269272RTDECL(int) RTDvmMapOpen(RTDVM hVolMgr)
    270273{
    271     int            rc = VINF_SUCCESS;
    272     uint32_t       uScoreMax = RTDVM_MATCH_SCORE_UNSUPPORTED;
     274    PRTDVMINTERNAL pThis = hVolMgr;
     275    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
     276    AssertReturn(pThis->u32Magic == RTDVM_MAGIC, VERR_INVALID_HANDLE);
     277    AssertReturn(pThis->hVolMgrFmt == NIL_RTDVMFMT, VERR_WRONG_ORDER);
     278
     279    Assert(!pThis->pDvmFmtOps);
     280
     281    /*
     282     * Let each format backend have a go at the disk, pick the one which scores the highest.
     283     */
     284    int            rc              = VINF_SUCCESS;
     285    uint32_t       uScoreMax       = RTDVM_MATCH_SCORE_UNSUPPORTED;
    273286    PCRTDVMFMTOPS  pDvmFmtOpsMatch = NULL;
    274     PRTDVMINTERNAL pThis = hVolMgr;
    275     AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
    276     AssertReturn(pThis->u32Magic == RTDVM_MAGIC, VERR_INVALID_HANDLE);
    277     AssertReturn(pThis->hVolMgrFmt == NIL_RTDVMFMT, VERR_INVALID_HANDLE);
    278 
    279     Assert(!pThis->pDvmFmtOps);
    280 
    281287    for (unsigned i = 0; i < RT_ELEMENTS(g_aDvmFmts); i++)
    282288    {
    283         uint32_t uScore;
     289        uint32_t uScore = 0;
    284290        PCRTDVMFMTOPS pDvmFmtOps = g_aDvmFmts[i];
    285291
    286292        rc = pDvmFmtOps->pfnProbe(&pThis->DvmDisk, &uScore);
    287         if (   RT_SUCCESS(rc)
    288             && uScore > uScoreMax)
     293        if (RT_SUCCESS(rc))
    289294        {
    290             pDvmFmtOpsMatch = pDvmFmtOps;
    291             uScoreMax       = uScore;
    292         }
    293         else if (RT_FAILURE(rc))
    294             break;
    295     }
    296 
    297     if (RT_SUCCESS(rc))
    298     {
    299         if (uScoreMax > RTDVM_MATCH_SCORE_UNSUPPORTED)
    300         {
    301             AssertPtr(pDvmFmtOpsMatch);
    302 
    303             /* Open the format. */
    304             rc = pDvmFmtOpsMatch->pfnOpen(&pThis->DvmDisk, &pThis->hVolMgrFmt);
    305             if (RT_SUCCESS(rc))
     295            if (uScore > uScoreMax)
    306296            {
    307                 uint32_t cVols;
    308 
    309                 pThis->pDvmFmtOps = pDvmFmtOpsMatch;
    310 
    311                 cVols = pThis->pDvmFmtOps->pfnGetValidVolumes(pThis->hVolMgrFmt);
    312 
    313                 /* Construct volume list. */
    314                 if (cVols)
    315                 {
    316                     PRTDVMVOLUMEINTERNAL pVol = NULL;
    317                     RTDVMVOLUMEFMT hVolFmt = NIL_RTDVMVOLUMEFMT;
    318 
    319                     rc = pThis->pDvmFmtOps->pfnQueryFirstVolume(pThis->hVolMgrFmt, &hVolFmt);
    320                     if (RT_SUCCESS(rc))
    321                     {
    322                         rc = rtDvmVolumeCreate(pThis, hVolFmt, &pVol);
    323                         if (RT_FAILURE(rc))
    324                             pThis->pDvmFmtOps->pfnVolumeClose(hVolFmt);
    325                     }
    326 
    327                     if (RT_SUCCESS(rc))
    328                     {
    329                         cVols--;
    330                         RTListAppend(&pThis->VolumeList, &pVol->VolumeNode);
    331 
    332                         while (   cVols > 0
    333                                && RT_SUCCESS(rc))
    334                         {
    335                             rc = pThis->pDvmFmtOps->pfnQueryNextVolume(pThis->hVolMgrFmt, pVol->hVolFmt, &hVolFmt);
    336                             if (RT_SUCCESS(rc))
    337                             {
    338                                 rc = rtDvmVolumeCreate(pThis, hVolFmt, &pVol);
    339                                 if (RT_FAILURE(rc))
    340                                     pThis->pDvmFmtOps->pfnVolumeClose(hVolFmt);
    341                                 else
    342                                     RTListAppend(&pThis->VolumeList, &pVol->VolumeNode);
    343                                 cVols--;
    344                             }
    345                         }
    346                     }
    347 
    348                     if (RT_FAILURE(rc))
    349                     {
    350                         /* Remove all entries. */
    351                         PRTDVMVOLUMEINTERNAL pItNext, pIt;
    352                         RTListForEachSafe(&pThis->VolumeList, pIt, pItNext, RTDVMVOLUMEINTERNAL, VolumeNode)
    353                         {
    354                             RTListNodeRemove(&pIt->VolumeNode);
    355                             rtDvmVolumeDestroy(pIt);
    356                         }
    357                     }
    358                 }
     297                pDvmFmtOpsMatch = pDvmFmtOps;
     298                uScoreMax       = uScore;
    359299            }
    360300        }
    361301        else
    362             rc = VERR_NOT_SUPPORTED;
    363     }
    364 
     302            return rc;
     303    }
     304    if (uScoreMax > RTDVM_MATCH_SCORE_UNSUPPORTED)
     305    {
     306        AssertPtr(pDvmFmtOpsMatch);
     307
     308        /*
     309         * Open the format.
     310         */
     311        rc = pDvmFmtOpsMatch->pfnOpen(&pThis->DvmDisk, &pThis->hVolMgrFmt);
     312        if (RT_SUCCESS(rc))
     313        {
     314            pThis->pDvmFmtOps = pDvmFmtOpsMatch;
     315
     316            /*
     317             * Construct volume list (we're done if none).
     318             */
     319            uint32_t cVols = pThis->pDvmFmtOps->pfnGetValidVolumes(pThis->hVolMgrFmt);
     320            if (cVols == 0)
     321                return VINF_SUCCESS;
     322
     323            /* First volume. */
     324            RTDVMVOLUMEFMT hVolFmt = NIL_RTDVMVOLUMEFMT;
     325            rc = pThis->pDvmFmtOps->pfnQueryFirstVolume(pThis->hVolMgrFmt, &hVolFmt);
     326            if (RT_SUCCESS(rc))
     327            {
     328                for (;;)
     329                {
     330                    PRTDVMVOLUMEINTERNAL pVol = NULL;
     331                    rc = rtDvmVolumeCreate(pThis, hVolFmt, &pVol);
     332                    if (RT_FAILURE(rc))
     333                    {
     334                        pThis->pDvmFmtOps->pfnVolumeClose(hVolFmt);
     335                        break;
     336                    }
     337                    RTListAppend(&pThis->VolumeList, &pVol->VolumeNode);
     338
     339                    /* Done?*/
     340                    cVols--;
     341                    if (cVols < 1)
     342                        return VINF_SUCCESS;
     343
     344                    /* Next volume. */
     345                    rc = pThis->pDvmFmtOps->pfnQueryNextVolume(pThis->hVolMgrFmt, pVol->hVolFmt, &hVolFmt);
     346                    if (RT_FAILURE(rc))
     347                        break;
     348                }
     349
     350                /* Bail out. */
     351                PRTDVMVOLUMEINTERNAL pItNext, pIt;
     352                RTListForEachSafe(&pThis->VolumeList, pIt, pItNext, RTDVMVOLUMEINTERNAL, VolumeNode)
     353                {
     354                    RTListNodeRemove(&pIt->VolumeNode);
     355                    rtDvmVolumeDestroy(pIt);
     356                }
     357            }
     358
     359            /** @todo shouldn't we close the format too here?  */
     360        }
     361    }
     362    else
     363        rc = VERR_NOT_SUPPORTED;
    365364    return rc;
    366365}
     
    368367RTDECL(int) RTDvmMapInitialize(RTDVM hVolMgr, const char *pszFmt)
    369368{
    370     int rc = VERR_NOT_SUPPORTED;
    371369    PRTDVMINTERNAL pThis = hVolMgr;
    372370    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
    373371    AssertPtrReturn(pszFmt, VERR_INVALID_POINTER);
    374372    AssertReturn(pThis->u32Magic == RTDVM_MAGIC, VERR_INVALID_HANDLE);
    375     AssertReturn(pThis->hVolMgrFmt == NIL_RTDVMFMT, VERR_INVALID_HANDLE);
     373    AssertReturn(pThis->hVolMgrFmt == NIL_RTDVMFMT, VERR_WRONG_ORDER);
    376374
    377375    for (unsigned i = 0; i < RT_ELEMENTS(g_aDvmFmts); i++)
    378376    {
    379377        PCRTDVMFMTOPS pDvmFmtOps = g_aDvmFmts[i];
    380 
    381378        if (!RTStrCmp(pDvmFmtOps->pcszFmt, pszFmt))
    382379        {
    383             rc = pDvmFmtOps->pfnInitialize(&pThis->DvmDisk, &pThis->hVolMgrFmt);
     380            int rc = pDvmFmtOps->pfnInitialize(&pThis->DvmDisk, &pThis->hVolMgrFmt);
    384381            if (RT_SUCCESS(rc))
    385382                pThis->pDvmFmtOps = pDvmFmtOps;
    386 
    387             break;
     383            return rc;
    388384        }
    389385    }
    390 
    391     return rc;
     386    return VERR_NOT_SUPPORTED;
    392387}
    393388
     
    444439RTDECL(int) RTDvmMapQueryNextVolume(RTDVM hVolMgr, RTDVMVOLUME hVol, PRTDVMVOLUME phVolNext)
    445440{
    446     int rc = VERR_DVM_MAP_NO_VOLUME;
    447441    PRTDVMINTERNAL       pThis = hVolMgr;
    448442    PRTDVMVOLUMEINTERNAL pVol = hVol;
     
    454448    AssertPtrReturn(phVolNext, VERR_INVALID_POINTER);
    455449
    456     PRTDVMVOLUMEINTERNAL pVolNext = RTListGetNext(&pThis->VolumeList, pVol,
    457                                                   RTDVMVOLUMEINTERNAL, VolumeNode);
     450    int rc = VERR_DVM_MAP_NO_VOLUME;
     451    PRTDVMVOLUMEINTERNAL pVolNext = RTListGetNext(&pThis->VolumeList, pVol, RTDVMVOLUMEINTERNAL, VolumeNode);
    458452    if (pVolNext)
    459453    {
     
    466460}
    467461
    468 RTDECL(int) RTDvmMapQueryBlockStatus(RTDVM hVolMgr, uint64_t off, uint64_t cb,
    469                                      bool *pfAllocated)
    470 {
    471     int rc = VINF_SUCCESS;
    472     PRTDVMINTERNAL       pThis = hVolMgr;
     462RTDECL(int) RTDvmMapQueryBlockStatus(RTDVM hVolMgr, uint64_t off, uint64_t cb, bool *pfAllocated)
     463{
     464    PRTDVMINTERNAL pThis = hVolMgr;
    473465    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
    474466    AssertPtrReturn(pfAllocated, VERR_INVALID_POINTER);
    475467    AssertReturn(pThis->u32Magic == RTDVM_MAGIC, VERR_INVALID_HANDLE);
    476     AssertReturn(pThis->hVolMgrFmt != NIL_RTDVMFMT, VERR_INVALID_HANDLE);
    477     AssertReturn(off + cb <= pThis->DvmDisk.cbDisk * pThis->DvmDisk.cbSector,
    478                  VERR_INVALID_PARAMETER);
     468    AssertReturn(pThis->hVolMgrFmt != NIL_RTDVMFMT, VERR_WRONG_ORDER);
     469    AssertMsgReturn(   off      <= pThis->DvmDisk.cbDisk
     470                    || cb       <= pThis->DvmDisk.cbDisk
     471                    || off + cb <= pThis->DvmDisk.cbDisk,
     472                    ("off=%#RX64 cb=%#RX64 cbDisk=%#RX64\n", off, cb, pThis->DvmDisk.cbDisk),
     473                    VERR_OUT_OF_RANGE);
    479474
    480475    /* Check whether the range is inuse by the volume manager metadata first. */
    481     rc = pThis->pDvmFmtOps->pfnQueryRangeUse(pThis->hVolMgrFmt, off, cb, pfAllocated);
     476    int rc = pThis->pDvmFmtOps->pfnQueryRangeUse(pThis->hVolMgrFmt, off, cb, pfAllocated);
    482477    if (RT_FAILURE(rc))
    483478        return rc;
     
    513508                    {
    514509                        bool fVolAllocated = true;
    515 
    516                         rc = pVol->pfnQueryBlockStatus(pVol->pvUser, offVol, cbIntersect,
    517                                                        &fVolAllocated);
     510                        rc = pVol->pfnQueryBlockStatus(pVol->pvUser, offVol, cbIntersect, &fVolAllocated);
    518511                        if (RT_FAILURE(rc))
    519512                            break;
    520                         else if (fVolAllocated)
     513                        if (fVolAllocated)
    521514                        {
    522515                            fAllocated = true;
     
    657650    AssertReturn(enmVolType >= RTDVMVOLTYPE_INVALID && enmVolType < RTDVMVOLTYPE_END, NULL);
    658651
    659     return g_apcszDvmVolTypes[enmVolType];
    660 }
     652    return g_apszDvmVolTypes[enmVolType];
     653}
     654
  • trunk/src/VBox/Runtime/common/dvm/dvmbsdlabel.cpp

    r69111 r69609  
    415415            if (pThis->DiskLabel.aPartitions[i].cSectors)
    416416            {
    417                 rc = rtDvmFmtBsdLblVolumeCreate(pThis, &pThis->DiskLabel.aPartitions[i],
    418                                               i, phVolFmt);
     417                rc = rtDvmFmtBsdLblVolumeCreate(pThis, &pThis->DiskLabel.aPartitions[i], i, phVolFmt);
    419418                break;
    420419            }
  • trunk/src/VBox/Runtime/common/dvm/dvmgpt.cpp

    r69111 r69609  
    4848 * GPT on disk header.
    4949 */
     50typedef struct GPTHDR
     51{
     52    /** 0x00: Signature ("EFI PART"). */
     53    char     abSignature[8];
     54    /** 0x08: Revision. */
     55    uint32_t u32Revision;
     56    /** 0x0c: Header size. */
     57    uint32_t cbHeader;
     58    /** 0x10: CRC of header. */
     59    uint32_t u32Crc;
     60} GPTHDR;
     61/** Pointer to a GPT header. */
     62typedef struct GPTHDR *PGPTHDR;
     63AssertCompileSize(GPTHDR, 20);
     64
     65/**
     66 * Complete GPT table header for revision 1.0.
     67 */
    5068#pragma pack(1)
    51 typedef struct GptHdr
    52 {
    53     /** Signature ("EFI PART"). */
    54     char     abSignature[8];
    55     /** Revision. */
    56     uint32_t u32Revision;
    57     /** Header size. */
    58     uint32_t cbHeader;
    59     /** CRC of header. */
    60     uint32_t u32Crc;
    61 } GptHdr;
    62 /** Pointer to a GPT header. */
    63 typedef struct GptHdr *PGptHdr;
     69typedef struct GPTHDRREV1
     70{
     71    /** 0x00: Header. */
     72    GPTHDR   Hdr;
     73    /** 0x14: Reserved. */
     74    uint32_t u32Reserved;
     75    /** 0x18: Current LBA. */
     76    uint64_t u64LbaCurrent;
     77    /** 0x20: Backup LBA. */
     78    uint64_t u64LbaBackup;
     79    /** 0x28:First usable LBA for partitions. */
     80    uint64_t u64LbaFirstPartition;
     81    /** 0x30: Last usable LBA for partitions. */
     82    uint64_t u64LbaLastPartition;
     83    /** 0x38: Disk UUID. */
     84    RTUUID   DiskUuid;
     85    /** 0x48: LBA of first partition entry. */
     86    uint64_t u64LbaPartitionEntries;
     87    /** 0x50: Number of partition entries. */
     88    uint32_t cPartitionEntries;
     89    /** 0x54: Partition entry size. */
     90    uint32_t cbPartitionEntry;
     91    /** 0x58: CRC of partition entries. */
     92    uint32_t u32CrcPartitionEntries;
     93} GPTHDRREV1;
     94/** Pointer to a revision 1.0 GPT header. */
     95typedef GPTHDRREV1 *PGPTHDRREV1;
    6496#pragma pack()
    65 AssertCompileSize(GptHdr, 20);
    66 
    67 /**
    68  * Complete GPT table header for revision 1.0.
    69  */
    70 #pragma pack(1)
    71 typedef struct GptHdrRev1
    72 {
    73     /** Header. */
    74     GptHdr   Hdr;
    75     /** Reserved. */
    76     uint32_t u32Reserved;
    77     /** Current LBA. */
    78     uint64_t u64LbaCurrent;
    79     /** Backup LBA. */
    80     uint64_t u64LbaBackup;
    81     /** First usable LBA for partitions. */
    82     uint64_t u64LbaFirstPartition;
    83     /** Last usable LBA for partitions. */
    84     uint64_t u64LbaLastPartition;
    85     /** Disk UUID. */
    86     RTUUID   DiskUuid;
    87     /** LBA of first partition entry. */
    88     uint64_t u64LbaPartitionEntries;
    89     /** Number of partition entries. */
    90     uint32_t cPartitionEntries;
    91     /** Partition entry size. */
    92     uint32_t cbPartitionEntry;
    93     /** CRC of partition entries. */
    94     uint32_t u32CrcPartitionEntries;
    95 } GptHdrRev1;
    96 /** Pointer to a revision 1.0 GPT header. */
    97 typedef GptHdrRev1 *PGptHdrRev1;
    98 #pragma pack()
    99 AssertCompileSize(GptHdrRev1, 92);
     97AssertCompileSize(GPTHDRREV1, 92);
    10098
    10199/**
    102100 * GPT partition table entry.
    103101 */
    104 #pragma pack(1)
    105 typedef struct GptEntry
    106 {
    107     /** Partition type UUID. */
     102typedef struct GPTENTRY
     103{
     104    /** 0x00: Partition type UUID. */
    108105    RTUUID   UuidType;
    109     /** Partition UUID. */
     106    /** 0x10: Partition UUID. */
    110107    RTUUID   UuidPartition;
    111     /** First LBA. */
     108    /** 0x20: First LBA. */
    112109    uint64_t u64LbaFirst;
    113     /** Last LBA. */
     110    /** 0x28: Last LBA. */
    114111    uint64_t u64LbaLast;
    115     /** Attribute flags. */
     112    /** 0x30: Attribute flags. */
    116113    uint64_t u64Flags;
    117     /** Partition name (UTF-16LE code units). */
     114    /** 0x38: Partition name (UTF-16LE code units). */
    118115    RTUTF16  aPartitionName[36];
    119 } GptEntry;
     116} GPTENTRY;
    120117/** Pointer to a GPT entry. */
    121 typedef struct GptEntry *PGptEntry;
    122 #pragma pack()
    123 AssertCompileSize(GptEntry, 128);
     118typedef struct GPTENTRY *PGPTENTRY;
     119AssertCompileSize(GPTENTRY, 128);
    124120
    125121/** Partition flags - System partition. */
     
    140136    PCRTDVMDISK     pDisk;
    141137    /** GPT header. */
    142     GptHdrRev1      HdrRev1;
     138    GPTHDRREV1      HdrRev1;
    143139    /** GPT array. */
    144     PGptEntry       paGptEntries;
     140    PGPTENTRY       paGptEntries;
    145141    /** Number of occupied partition entries. */
    146142    uint32_t        cPartitions;
     
    163159    uint64_t          cbVolume;
    164160    /** Pointer to the GPT entry in the array. */
    165     PGptEntry         pGptEntry;
     161    PGPTENTRY         pGptEntry;
    166162} RTDVMVOLUMEFMTINTERNAL;
    167163/** Pointer to an MBR volume. */
     
    232228{
    233229    int rc = VINF_SUCCESS;
    234     GptHdr Hdr;
     230    GPTHDR Hdr;
    235231
    236232    *puScore = RTDVM_MATCH_SCORE_UNSUPPORTED;
     
    239235    {
    240236        /* Read from the disk and check for the signature. */
    241         rc = rtDvmDiskRead(pDisk, RTDVM_GPT_LBA2BYTE(1, pDisk), &Hdr, sizeof(GptHdr));
     237        rc = rtDvmDiskRead(pDisk, RTDVM_GPT_LBA2BYTE(1, pDisk), &Hdr, sizeof(GPTHDR));
    242238        if (   RT_SUCCESS(rc)
    243239            && !strncmp(&Hdr.abSignature[0], RTDVM_GPT_SIGNATURE, RT_ELEMENTS(Hdr.abSignature))
    244240            && RT_LE2H_U32(Hdr.u32Revision) == 0x00010000
    245             && RT_LE2H_U32(Hdr.cbHeader)    == sizeof(GptHdrRev1))
     241            && RT_LE2H_U32(Hdr.cbHeader)    == sizeof(GPTHDRREV1))
    246242            *puScore = RTDVM_MATCH_SCORE_PERFECT;
    247243    }
     
    278274            pThis->HdrRev1.u32CrcPartitionEntries = RT_LE2H_U32(pThis->HdrRev1.u32CrcPartitionEntries);
    279275
    280             if (pThis->HdrRev1.cbPartitionEntry == sizeof(GptEntry))
     276            if (pThis->HdrRev1.cbPartitionEntry == sizeof(GPTENTRY))
    281277            {
    282                 pThis->paGptEntries = (PGptEntry)RTMemAllocZ(pThis->HdrRev1.cPartitionEntries * pThis->HdrRev1.cbPartitionEntry);
     278                pThis->paGptEntries = (PGPTENTRY)RTMemAllocZ(pThis->HdrRev1.cPartitionEntries * pThis->HdrRev1.cbPartitionEntry);
    283279                if (pThis->paGptEntries)
    284280                {
     
    381377 * @param   phVolFmt      Where to store the volume data on success.
    382378 */
    383 static int rtDvmFmtMbrVolumeCreate(PRTDVMFMTINTERNAL pThis, PGptEntry pGptEntry,
     379static int rtDvmFmtMbrVolumeCreate(PRTDVMFMTINTERNAL pThis, PGPTENTRY pGptEntry,
    384380                                 uint32_t idx, PRTDVMVOLUMEFMT phVolFmt)
    385381{
     
    405401static DECLCALLBACK(int) rtDvmFmtGptQueryFirstVolume(RTDVMFMT hVolMgrFmt, PRTDVMVOLUMEFMT phVolFmt)
    406402{
    407     int rc = VINF_SUCCESS;
    408403    PRTDVMFMTINTERNAL pThis = hVolMgrFmt;
    409404
    410405    if (pThis->cPartitions != 0)
    411406    {
    412         PGptEntry pGptEntry = &pThis->paGptEntries[0];
     407        PGPTENTRY pGptEntry = &pThis->paGptEntries[0];
    413408
    414409        /* Search for the first non empty entry. */
     
    416411        {
    417412            if (!RTUuidIsNull(&pGptEntry->UuidType))
    418             {
    419                 rc = rtDvmFmtMbrVolumeCreate(pThis, pGptEntry, i, phVolFmt);
    420                 break;
    421             }
     413                return rtDvmFmtMbrVolumeCreate(pThis, pGptEntry, i, phVolFmt);
    422414            pGptEntry++;
    423415        }
     416        AssertFailed();
    424417    }
    425     else
    426         rc = VERR_DVM_MAP_EMPTY;
    427 
    428     return rc;
     418    return VERR_DVM_MAP_EMPTY;
    429419}
    430420
    431421static DECLCALLBACK(int) rtDvmFmtGptQueryNextVolume(RTDVMFMT hVolMgrFmt, RTDVMVOLUMEFMT hVolFmt, PRTDVMVOLUMEFMT phVolFmtNext)
    432422{
    433     int rc = VERR_DVM_MAP_NO_VOLUME;
    434423    PRTDVMFMTINTERNAL pThis = hVolMgrFmt;
    435424    PRTDVMVOLUMEFMTINTERNAL pVol = hVolFmt;
    436     PGptEntry pGptEntry = pVol->pGptEntry + 1;
     425    PGPTENTRY pGptEntry = pVol->pGptEntry + 1;
    437426
    438427    for (unsigned i = pVol->idxEntry + 1; i < pThis->HdrRev1.cPartitionEntries; i++)
    439428    {
    440429        if (!RTUuidIsNull(&pGptEntry->UuidType))
    441         {
    442             rc = rtDvmFmtMbrVolumeCreate(pThis, pGptEntry, i, phVolFmtNext);
    443             break;
    444         }
     430            return rtDvmFmtMbrVolumeCreate(pThis, pGptEntry, i, phVolFmtNext);
    445431        pGptEntry++;
    446432    }
    447433
    448     return rc;
     434    return VERR_DVM_MAP_NO_VOLUME;
    449435}
    450436
     
    471457{
    472458    PRTDVMVOLUMEFMTINTERNAL pVol = hVolFmt;
    473     int rc = VINF_SUCCESS;
    474459
    475460    *ppszVolName = NULL;
    476     rc = RTUtf16ToUtf8Ex(&pVol->pGptEntry->aPartitionName[0], RT_ELEMENTS(pVol->pGptEntry->aPartitionName),
    477                          ppszVolName, 0, NULL);
    478 
    479     return rc;
     461    return RTUtf16ToUtf8Ex(&pVol->pGptEntry->aPartitionName[0], RT_ELEMENTS(pVol->pGptEntry->aPartitionName),
     462                           ppszVolName, 0, NULL);
    480463}
    481464
    482465static DECLCALLBACK(RTDVMVOLTYPE) rtDvmFmtGptVolumeGetType(RTDVMVOLUMEFMT hVolFmt)
    483466{
    484     RTDVMVOLTYPE enmVolType = RTDVMVOLTYPE_UNKNOWN;
    485467    PRTDVMVOLUMEFMTINTERNAL pVol = hVolFmt;
    486468
    487469    for (unsigned i = 0; i < RT_ELEMENTS(g_aPartType2DvmVolTypes); i++)
    488470        if (!RTUuidCompareStr(&pVol->pGptEntry->UuidType, g_aPartType2DvmVolTypes[i].pcszUuid))
    489         {
    490             enmVolType = g_aPartType2DvmVolTypes[i].enmVolType;
    491             break;
    492         }
    493 
    494     return enmVolType;
     471            return g_aPartType2DvmVolTypes[i].enmVolType;
     472
     473    return RTDVMVOLTYPE_UNKNOWN;
    495474}
    496475
     
    506485                                                               uint64_t *pcbIntersect)
    507486{
    508     bool fIntersect = false;
    509487    PRTDVMVOLUMEFMTINTERNAL pVol = hVolFmt;
    510488
    511489    if (RTDVM_RANGE_IS_INTERSECTING(pVol->offStart, pVol->cbVolume, offStart))
    512490    {
    513         fIntersect    = true;
    514491        *poffVol      = offStart - pVol->offStart;
    515492        *pcbIntersect = RT_MIN(cbRange, pVol->offStart + pVol->cbVolume - offStart);
     493        return true;
    516494    }
    517 
    518     return fIntersect;
     495    return false;
    519496}
    520497
  • trunk/src/VBox/Runtime/common/dvm/dvmvfs.cpp

    r69111 r69609  
    2929*   Header Files                                                                                                                 *
    3030*********************************************************************************************************************************/
     31#define LOG_GROUP RTLOGGROUP_FS /** @todo fix log group  */
    3132#include <iprt/types.h>
    3233#include <iprt/assert.h>
     
    4041#include <iprt/vfslowlevel.h>
    4142#include <iprt/poll.h>
     43#include <iprt/log.h>
    4244#include "internal/dvm.h"
    4345
     
    5961/** Pointer to a the internal data of a DVM volume file. */
    6062typedef RTVFSDVMFILE *PRTVFSDVMFILE;
     63
     64/**
     65 * A volume manager VFS for use in chains (thing pseudo/devfs).
     66 */
     67typedef struct RTDVMVFSVOL
     68{
     69    /** The volume manager. */
     70    RTDVM       hVolMgr;
     71    /** Whether to close it on success. */
     72    bool        fCloseDvm;
     73    /** Whether the access is read-only. */
     74    bool        fReadOnly;
     75    /** Number of volumes. */
     76    uint32_t    cVolumes;
     77} RTDVMVFSVOL;
     78/** Poitner to a volume manager VFS. */
     79typedef RTDVMVFSVOL *PRTDVMVFSVOL;
     80
     81/**
     82 * The volume manager VFS root dir data.
     83 */
     84typedef struct RTDVMVFSROOTDIR
     85{
     86    /** Pointer to the VFS volume. */
     87    PRTDVMVFSVOL    pVfsVol;
     88    /** The current directory offset. */
     89    uint32_t        offDir;
     90} RTDVMVFSROOTDIR;
     91/** Poitner to a volume manager VFS root dir. */
     92typedef RTDVMVFSROOTDIR *PRTDVMVFSROOTDIR;
    6193
    6294
     
    413445}
    414446
     447
     448
     449
     450/**
     451 * @interface_method_impl{RTVFSOBJOPS::Obj,pfnClose}
     452 */
     453static DECLCALLBACK(int) rtDvmVfsVol_Close(void *pvThis)
     454{
     455    PRTDVMVFSVOL pThis = (PRTDVMVFSVOL)pvThis;
     456    LogFlow(("rtDvmVfsVol_Close(%p)\n", pThis));
     457
     458    if (   pThis->fCloseDvm
     459        && pThis->hVolMgr != NIL_RTDVM )
     460        RTDvmRelease(pThis->hVolMgr);
     461    pThis->hVolMgr = NIL_RTDVM;
     462
     463    return VINF_SUCCESS;
     464}
     465
     466
     467/**
     468 * @interface_method_impl{RTVFSOBJOPS::Obj,pfnQueryInfo}
     469 */
     470static DECLCALLBACK(int) rtDvmVfsVol_QueryInfo(void *pvThis, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAddAttr)
     471{
     472    RT_NOREF(pvThis, pObjInfo, enmAddAttr);
     473    return VERR_WRONG_TYPE;
     474}
     475
     476
     477/**
     478 * @interface_method_impl{RTVFSOPS,pfnOpenRoot}
     479 */
     480static DECLCALLBACK(int) rtDvmVfsVol_OpenRoot(void *pvThis, PRTVFSDIR phVfsDir)
     481{
     482    //PRTDVMVFSVOL pThis = (PRTDVMVFSVOL)pvThis;
     483
     484    //rtDvmDirShrd_Retain(pThis->pRootDir); /* consumed by the next call */
     485    //return rtDvmDir_NewWithShared(pThis, pThis->pRootDir, phVfsDir);
     486    RT_NOREF(pvThis, phVfsDir);
     487    return VERR_NOT_IMPLEMENTED;
     488}
     489
     490
     491/**
     492 * @interface_method_impl{RTVFSOPS,pfnIsRangeInUse}
     493 */
     494static DECLCALLBACK(int) rtDvmVfsVol_IsRangeInUse(void *pvThis, RTFOFF off, size_t cb, bool *pfUsed)
     495{
     496    RT_NOREF(pvThis, off, cb, pfUsed);
     497    return VERR_NOT_IMPLEMENTED;
     498}
     499
     500
     501DECL_HIDDEN_CONST(const RTVFSOPS) g_rtDvmVfsVolOps =
     502{
     503    { /* Obj */
     504        RTVFSOBJOPS_VERSION,
     505        RTVFSOBJTYPE_VFS,
     506        "DvmVol",
     507        rtDvmVfsVol_Close,
     508        rtDvmVfsVol_QueryInfo,
     509        RTVFSOBJOPS_VERSION
     510    },
     511    RTVFSOPS_VERSION,
     512    0 /* fFeatures */,
     513    rtDvmVfsVol_OpenRoot,
     514    rtDvmVfsVol_IsRangeInUse,
     515    RTVFSOPS_VERSION
     516};
     517
     518
     519
     520/**
     521 * @interface_method_impl{RTVFSCHAINELEMENTREG,pfnValidate}
     522 */
     523static DECLCALLBACK(int) rtDvmVfsChain_Validate(PCRTVFSCHAINELEMENTREG pProviderReg, PRTVFSCHAINSPEC pSpec,
     524                                                PRTVFSCHAINELEMSPEC pElement, uint32_t *poffError, PRTERRINFO pErrInfo)
     525{
     526    RT_NOREF(pProviderReg, pSpec);
     527
     528    /*
     529     * Basic checks.
     530     */
     531    if (pElement->enmTypeIn != RTVFSOBJTYPE_FILE)
     532        return pElement->enmTypeIn == RTVFSOBJTYPE_INVALID ? VERR_VFS_CHAIN_CANNOT_BE_FIRST_ELEMENT : VERR_VFS_CHAIN_TAKES_FILE;
     533    if (pElement->enmType != RTVFSOBJTYPE_VFS)
     534        return VERR_VFS_CHAIN_ONLY_VFS;
     535
     536    if (pElement->cArgs > 1)
     537        return VERR_VFS_CHAIN_AT_MOST_ONE_ARG;
     538
     539    /*
     540     * Parse the flag if present, save in pElement->uProvider.
     541     */
     542    /** @todo allow specifying sector size   */
     543    bool fReadOnly = (pSpec->fOpenFile & RTFILE_O_ACCESS_MASK) == RTFILE_O_READ;
     544    if (pElement->cArgs > 0)
     545    {
     546        const char *psz = pElement->paArgs[0].psz;
     547        if (*psz)
     548        {
     549            if (   !strcmp(psz, "ro")
     550                || !strcmp(psz, "r"))
     551                fReadOnly = true;
     552            else if (!strcmp(psz, "rw"))
     553                fReadOnly = false;
     554            else
     555            {
     556                *poffError = pElement->paArgs[0].offSpec;
     557                return RTErrInfoSet(pErrInfo, VERR_VFS_CHAIN_INVALID_ARGUMENT, "Expected 'ro' or 'rw' as argument");
     558            }
     559        }
     560    }
     561
     562    pElement->uProvider = fReadOnly;
     563    return VINF_SUCCESS;
     564}
     565
     566
     567/**
     568 * @interface_method_impl{RTVFSCHAINELEMENTREG,pfnInstantiate}
     569 */
     570static DECLCALLBACK(int) rtDvmVfsChain_Instantiate(PCRTVFSCHAINELEMENTREG pProviderReg, PCRTVFSCHAINSPEC pSpec,
     571                                                   PCRTVFSCHAINELEMSPEC pElement, RTVFSOBJ hPrevVfsObj,
     572                                                   PRTVFSOBJ phVfsObj, uint32_t *poffError, PRTERRINFO pErrInfo)
     573{
     574    RT_NOREF(pProviderReg, pSpec, poffError, pErrInfo);
     575    AssertReturn(hPrevVfsObj != NIL_RTVFSOBJ, VERR_VFS_CHAIN_IPE);
     576
     577    /*
     578     * Instantiate the volume manager and open the map stuff.
     579     */
     580    RTVFSFILE hPrevVfsFile = RTVfsObjToFile(hPrevVfsObj);
     581    AssertReturn(hPrevVfsFile != NIL_RTVFSFILE, VERR_VFS_CHAIN_CAST_FAILED);
     582
     583    RTDVM hVolMgr;
     584    int rc = RTDvmCreate(&hVolMgr, hPrevVfsFile, 512, 0 /*fFlags*/);
     585    RTVfsFileRelease(hPrevVfsFile);
     586    if (RT_SUCCESS(rc))
     587    {
     588        rc = RTDvmMapOpen(hVolMgr);
     589        if (RT_SUCCESS(rc))
     590        {
     591            /*
     592             * Create a VFS instance for the volume manager.
     593             */
     594            RTVFS        hVfs  = NIL_RTVFS;
     595            PRTDVMVFSVOL pThis = NULL;
     596            int rc = RTVfsNew(&g_rtDvmVfsVolOps, sizeof(RTDVMVFSVOL), NIL_RTVFS, RTVFSLOCK_CREATE_RW, &hVfs, (void **)&pThis);
     597            if (RT_SUCCESS(rc))
     598            {
     599                pThis->hVolMgr   = hVolMgr;
     600                pThis->fCloseDvm = true;
     601                pThis->fReadOnly = pElement->uProvider == (uint64_t)true;
     602                pThis->cVolumes  = RTDvmMapGetValidVolumes(hVolMgr);
     603
     604                *phVfsObj = RTVfsObjFromVfs(hVfs);
     605                RTVfsRelease(hVfs);
     606                return *phVfsObj != NIL_RTVFSOBJ ? VINF_SUCCESS : VERR_VFS_CHAIN_CAST_FAILED;
     607            }
     608        }
     609        else
     610            rc = RTErrInfoSetF(pErrInfo, rc, "RTDvmMapOpen failed: %Rrc", rc);
     611        RTDvmRelease(hVolMgr);
     612    }
     613    else
     614        rc = RTErrInfoSetF(pErrInfo, rc, "RTDvmCreate failed: %Rrc", rc);
     615    return rc;
     616}
     617
     618
     619/**
     620 * @interface_method_impl{RTVFSCHAINELEMENTREG,pfnCanReuseElement}
     621 */
     622static DECLCALLBACK(bool) rtDvmVfsChain_CanReuseElement(PCRTVFSCHAINELEMENTREG pProviderReg,
     623                                                        PCRTVFSCHAINSPEC pSpec, PCRTVFSCHAINELEMSPEC pElement,
     624                                                        PCRTVFSCHAINSPEC pReuseSpec, PCRTVFSCHAINELEMSPEC pReuseElement)
     625{
     626    RT_NOREF(pProviderReg, pSpec, pElement, pReuseSpec, pReuseElement);
     627    return false;
     628}
     629
     630
     631/** VFS chain element 'file'. */
     632static RTVFSCHAINELEMENTREG g_rtVfsChainIsoFsVolReg =
     633{
     634    /* uVersion = */            RTVFSCHAINELEMENTREG_VERSION,
     635    /* fReserved = */           0,
     636    /* pszName = */             "dvm",
     637    /* ListEntry = */           { NULL, NULL },
     638    /* pszHelp = */             "Opens a container image using the VD API.\n",
     639    /* pfnValidate = */         rtDvmVfsChain_Validate,
     640    /* pfnInstantiate = */      rtDvmVfsChain_Instantiate,
     641    /* pfnCanReuseElement = */  rtDvmVfsChain_CanReuseElement,
     642    /* uEndMarker = */          RTVFSCHAINELEMENTREG_VERSION
     643};
     644
     645RTVFSCHAIN_AUTO_REGISTER_ELEMENT_PROVIDER(&g_rtVfsChainIsoFsVolReg, rtVfsChainIsoFsVolReg);
     646
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