VirtualBox

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


Ignore:
Timestamp:
Jul 16, 2018 12:37:19 PM (6 years ago)
Author:
vboxsync
Message:

IPRT/DVM: Added more GUID and partition types. The VFS directory enum now returns symlink objects with the partition name linking to volXX when a name is present (there can be duplicates).

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

Legend:

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

    r69967 r73156  
    121121    "FAT16",
    122122    "FAT32",
     123
     124    "EFI system partition",
     125
     126    "Mac OS X HFS or HFS+",
     127    "Mac OS X APFS",
     128
    123129    "Linux swap",
    124130    "Linux native",
    125131    "Linux LVM",
    126132    "Linux SoftRaid",
     133
    127134    "FreeBSD",
    128135    "NetBSD",
    129136    "OpenBSD",
    130     "Mac OS X HFS or HFS+",
    131     "Solaris"
     137    "Solaris",
     138
     139    "Basic data partition",
     140    "Microsoft reserved partition",
     141    "Windows LDM metadata",
     142    "Windows LDM data",
     143    "Windows recovery partition",
     144    "Windows storage spaces",
     145
     146    "IBM GPFS",
    132147};
    133148AssertCompile(RT_ELEMENTS(g_apszDvmVolTypes) == RTDVMVOLTYPE_END);
  • trunk/src/VBox/Runtime/common/dvm/dvmgpt.cpp

    r69616 r73156  
    194194static const RTDVMGPTPARTTYPE2VOLTYPE g_aPartType2DvmVolTypes[] =
    195195{
    196     {"0657FD6D-A4AB-43C4-84E5-0933C84B4F4F", RTDVMVOLTYPE_LINUX_SWAP},
    197     {"EBD0A0A2-B9E5-4433-87C0-68B6B72699C7", RTDVMVOLTYPE_LINUX_NATIVE},
    198     {"E6D6D379-F507-44C2-A23C-238F2A3DF928", RTDVMVOLTYPE_LINUX_LVM},
    199     {"A19D880F-05FC-4D3B-A006-743F0F84911E", RTDVMVOLTYPE_LINUX_SOFTRAID},
    200 
    201     {"83BD6B9D-7F41-11DC-BE0B-001560B84F0F", RTDVMVOLTYPE_FREEBSD}, /* Boot */
    202     {"516E7CB4-6ECF-11D6-8FF8-00022D09712B", RTDVMVOLTYPE_FREEBSD}, /* Data */
    203     {"516E7CB5-6ECF-11D6-8FF8-00022D09712B", RTDVMVOLTYPE_FREEBSD}, /* Swap */
    204     {"516E7CB6-6ECF-11D6-8FF8-00022D09712B", RTDVMVOLTYPE_FREEBSD}, /* UFS */
    205     {"516E7CB8-6ECF-11D6-8FF8-00022D09712B", RTDVMVOLTYPE_FREEBSD}, /* Vinum */
    206     {"516E7CBA-6ECF-11D6-8FF8-00022D09712B", RTDVMVOLTYPE_FREEBSD}, /* ZFS */
    207 
    208     {"49F48D32-B10E-11DC-B99B-0019D1879648", RTDVMVOLTYPE_NETBSD}, /* Swap */
    209     {"49F48D5A-B10E-11DC-B99B-0019D1879648", RTDVMVOLTYPE_NETBSD}, /* FFS */
    210     {"49F48D82-B10E-11DC-B99B-0019D1879648", RTDVMVOLTYPE_NETBSD}, /* LFS */
    211     {"49F48DAA-B10E-11DC-B99B-0019D1879648", RTDVMVOLTYPE_NETBSD}, /* Raid */
    212     {"2DB519C4-B10F-11DC-B99B-0019D1879648", RTDVMVOLTYPE_NETBSD}, /* Concatenated */
    213     {"2DB519EC-B10F-11DC-B99B-0019D1879648", RTDVMVOLTYPE_NETBSD}, /* Encrypted */
    214 
    215     {"48465300-0000-11AA-AA11-00306543ECAC", RTDVMVOLTYPE_MAC_OSX_HFS},
    216 
    217     {"6A82CB45-1DD2-11B2-99A6-080020736631", RTDVMVOLTYPE_SOLARIS}, /* Boot */
    218     {"6A85CF4D-1DD2-11B2-99A6-080020736631", RTDVMVOLTYPE_SOLARIS}, /* Root */
    219     {"6A87C46F-1DD2-11B2-99A6-080020736631", RTDVMVOLTYPE_SOLARIS}, /* Swap */
    220     {"6A8B642B-1DD2-11B2-99A6-080020736631", RTDVMVOLTYPE_SOLARIS}, /* Backup */
    221     {"6A898CC3-1DD2-11B2-99A6-080020736631", RTDVMVOLTYPE_SOLARIS}, /* /usr */
    222     {"6A8EF2E9-1DD2-11B2-99A6-080020736631", RTDVMVOLTYPE_SOLARIS}, /* /var */
    223     {"6A90BA39-1DD2-11B2-99A6-080020736631", RTDVMVOLTYPE_SOLARIS}, /* /home */
    224     {"6A9283A5-1DD2-11B2-99A6-080020736631", RTDVMVOLTYPE_SOLARIS}, /* Alternate sector */
     196    { "C12A7328-F81F-11D2-BA4B-00A0C93EC93B", RTDVMVOLTYPE_EFI_SYSTEM },
     197
     198    { "EBD0A0A2-B9E5-4433-87C0-68B6B72699C7", RTDVMVOLTYPE_WIN_BASIC },
     199    { "E3C9E316-0B5C-4DB8-817D-F92DF00215AE", RTDVMVOLTYPE_WIN_MSR },
     200    { "5808C8AA-7E8F-42E0-85D2-E1E90434CFB3", RTDVMVOLTYPE_WIN_LDM_META },
     201    { "AF9B60A0-1431-4F62-BC68-3311714A69AD", RTDVMVOLTYPE_WIN_LDM_DATA },
     202    { "DE94BBA4-06D1-4D40-A16A-BFD50179D6AC", RTDVMVOLTYPE_WIN_RECOVERY },
     203    { "E75CAF8F-F680-4CEE-AFA3-B001E56EFC2D", RTDVMVOLTYPE_WIN_STORAGE_SPACES },
     204
     205    { "0657FD6D-A4AB-43C4-84E5-0933C84B4F4F", RTDVMVOLTYPE_LINUX_SWAP },
     206    { "0FC63DAF-8483-4772-8E79-3D69D8477DE4", RTDVMVOLTYPE_LINUX_NATIVE },
     207    { "44479540-F297-41B2-9AF7-D131D5F0458A", RTDVMVOLTYPE_LINUX_NATIVE }, /* x86 root */
     208    { "4F68BCE3-E8CD-4DB1-96E7-FBCAF984B709", RTDVMVOLTYPE_LINUX_NATIVE }, /* AMD64 root */
     209    { "69DAD710-2CE4-4E3C-B16C-21A1D49ABED3", RTDVMVOLTYPE_LINUX_NATIVE }, /* ARM32 root */
     210    { "B921B045-1DF0-41C3-AF44-4C6F280D3FAE", RTDVMVOLTYPE_LINUX_NATIVE }, /* ARM64 root */
     211    { "E6D6D379-F507-44C2-A23C-238F2A3DF928", RTDVMVOLTYPE_LINUX_LVM },
     212    { "A19D880F-05FC-4D3B-A006-743F0F84911E", RTDVMVOLTYPE_LINUX_SOFTRAID },
     213
     214    { "83BD6B9D-7F41-11DC-BE0B-001560B84F0F", RTDVMVOLTYPE_FREEBSD }, /* Boot */
     215    { "516E7CB4-6ECF-11D6-8FF8-00022D09712B", RTDVMVOLTYPE_FREEBSD }, /* Data */
     216    { "516E7CB5-6ECF-11D6-8FF8-00022D09712B", RTDVMVOLTYPE_FREEBSD }, /* Swap */
     217    { "516E7CB6-6ECF-11D6-8FF8-00022D09712B", RTDVMVOLTYPE_FREEBSD }, /* UFS */
     218    { "516E7CB8-6ECF-11D6-8FF8-00022D09712B", RTDVMVOLTYPE_FREEBSD }, /* Vinum */
     219    { "516E7CBA-6ECF-11D6-8FF8-00022D09712B", RTDVMVOLTYPE_FREEBSD }, /* ZFS */
     220
     221    { "49F48D32-B10E-11DC-B99B-0019D1879648", RTDVMVOLTYPE_NETBSD }, /* Swap */
     222    { "49F48D5A-B10E-11DC-B99B-0019D1879648", RTDVMVOLTYPE_NETBSD }, /* FFS */
     223    { "49F48D82-B10E-11DC-B99B-0019D1879648", RTDVMVOLTYPE_NETBSD }, /* LFS */
     224    { "49F48DAA-B10E-11DC-B99B-0019D1879648", RTDVMVOLTYPE_NETBSD }, /* Raid */
     225    { "2DB519C4-B10F-11DC-B99B-0019D1879648", RTDVMVOLTYPE_NETBSD }, /* Concatenated */
     226    { "2DB519EC-B10F-11DC-B99B-0019D1879648", RTDVMVOLTYPE_NETBSD }, /* Encrypted */
     227
     228    { "48465300-0000-11AA-AA11-00306543ECAC", RTDVMVOLTYPE_DARWIN_HFS },
     229    { "7C3457EF-0000-11AA-AA11-00306543ECAC", RTDVMVOLTYPE_DARWIN_APFS },
     230
     231    { "6A82CB45-1DD2-11B2-99A6-080020736631", RTDVMVOLTYPE_SOLARIS }, /* Boot */
     232    { "6A85CF4D-1DD2-11B2-99A6-080020736631", RTDVMVOLTYPE_SOLARIS }, /* Root */
     233    { "6A87C46F-1DD2-11B2-99A6-080020736631", RTDVMVOLTYPE_SOLARIS }, /* Swap */
     234    { "6A8B642B-1DD2-11B2-99A6-080020736631", RTDVMVOLTYPE_SOLARIS }, /* Backup */
     235    { "6A898CC3-1DD2-11B2-99A6-080020736631", RTDVMVOLTYPE_SOLARIS }, /* /usr */
     236    { "6A8EF2E9-1DD2-11B2-99A6-080020736631", RTDVMVOLTYPE_SOLARIS }, /* /var */
     237    { "6A90BA39-1DD2-11B2-99A6-080020736631", RTDVMVOLTYPE_SOLARIS }, /* /home */
     238    { "6A9283A5-1DD2-11B2-99A6-080020736631", RTDVMVOLTYPE_SOLARIS }, /* Alternate sector */
     239
     240    { "37AFFC90-EF7D-4E96-91C3-2D7AE055B174", RTDVMVOLTYPE_IBM_GPFS },
    225241};
    226242
  • trunk/src/VBox/Runtime/common/dvm/dvmmbr.cpp

    r69909 r73156  
    176176    { 0xa9, RTDVMVOLTYPE_NETBSD },
    177177    { 0xa6, RTDVMVOLTYPE_OPENBSD },
    178     { 0xaf, RTDVMVOLTYPE_MAC_OSX_HFS },
     178    { 0xaf, RTDVMVOLTYPE_DARWIN_HFS },
    179179    { 0xbf, RTDVMVOLTYPE_SOLARIS },
    180180    { 0xfd, RTDVMVOLTYPE_LINUX_SOFTRAID }
  • trunk/src/VBox/Runtime/common/dvm/dvmvfs.cpp

    r73097 r73156  
    4848*   Structures and Typedefs                                                                                                      *
    4949*********************************************************************************************************************************/
    50 /**
    51  * A volume manager VFS for use in chains (thing pseudo/devfs).
    52  */
    53 typedef struct RTDVMVFSVOL
    54 {
    55     /** The volume manager. */
    56     RTDVM           hVolMgr;
    57     /** Whether to close it on success. */
    58     bool            fCloseDvm;
    59     /** Whether the access is read-only. */
    60     bool            fReadOnly;
    61     /** Number of volumes. */
    62     uint32_t        cVolumes;
    63     /** Self reference. */
    64     RTVFS           hVfsSelf;
    65 } RTDVMVFSVOL;
    66 /** Poitner to a volume manager VFS. */
    67 typedef RTDVMVFSVOL *PRTDVMVFSVOL;
    68 
    69 /**
    70  * The volume manager VFS (root) dir data.
    71  */
    72 typedef struct RTDVMVFSDIR
    73 {
    74     /** Pointer to the VFS volume. */
    75     PRTDVMVFSVOL    pVfsVol;
    76     /** The current directory offset. */
    77     uint32_t        offDir;
    78     /** Set if we need to try return hCurVolume again because of buffer overflow. */
    79     bool            fReturnCurrent;
    80     /** The current DVM volume. */
    81     RTDVMVOLUME     hCurVolume;
    82 } RTDVMVFSDIR;
    83 /** Poitner to a volume manager VFS (root) dir. */
    84 typedef RTDVMVFSDIR *PRTDVMVFSDIR;
     50/** Pointer to a volume manager VFS. */
     51typedef struct RTDVMVFSVOL *PRTDVMVFSVOL;
    8552
    8653/**
     
    10370typedef RTVFSDVMFILE *PRTVFSDVMFILE;
    10471
     72/**
     73 * The internal data of a DVM volume symlink.
     74 */
     75typedef struct RTVFSDVMSYMLINK
     76{
     77    /** The DVM volume the symlink represent. */
     78    RTDVMVOLUME     hVol;
     79    /** The DVM volume manager @a hVol belongs to. */
     80    RTDVM           hVolMgr;
     81    /** The symlink name. */
     82    char           *pszSymlink;
     83    /** The symlink target (volXX). */
     84    char            szTarget[16];
     85} RTVFSDVMSYMLINK;
     86/** Pointer to a the internal data of a DVM volume file. */
     87typedef RTVFSDVMSYMLINK *PRTVFSDVMSYMLINK;
     88
     89/**
     90 * The volume manager VFS (root) dir data.
     91 */
     92typedef struct RTDVMVFSDIR
     93{
     94    /** Pointer to the VFS volume. */
     95    PRTDVMVFSVOL    pVfsVol;
     96    /** The current directory offset. */
     97    uint32_t        offDir;
     98    /** Set if we need to try return hCurVolume again because of buffer overflow. */
     99    bool            fReturnCurrent;
     100    /** Pointer to name alias string (returned by RTDvmVolumeQueryName, free it). */
     101    char           *pszNameAlias;
     102    /** The current DVM volume. */
     103    RTDVMVOLUME     hCurVolume;
     104} RTDVMVFSDIR;
     105/** Pointer to a volume manager VFS (root) dir. */
     106typedef RTDVMVFSDIR *PRTDVMVFSDIR;
     107
     108/**
     109 * A volume manager VFS for use in chains (thing pseudo/devfs).
     110 */
     111typedef struct RTDVMVFSVOL
     112{
     113    /** The volume manager. */
     114    RTDVM           hVolMgr;
     115    /** Whether to close it on success. */
     116    bool            fCloseDvm;
     117    /** Whether the access is read-only. */
     118    bool            fReadOnly;
     119    /** Number of volumes. */
     120    uint32_t        cVolumes;
     121    /** Self reference. */
     122    RTVFS           hVfsSelf;
     123} RTDVMVFSVOL;
     124
    105125
    106126/*********************************************************************************************************************************
     
    123143
    124144/**
    125  * Worker for rtDvmVfsFile_QueryInfo, rtDvmVfsDir_QueryEntryInfo, and
    126  * rtDvmVfsDir_ReadDir.
    127  */
    128 static int rtDvmVfsFile_QueryInfoWorker(RTDVMVOLUME hVolume, RTDVM hVolMgr, bool fReadOnly,
    129                                         PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAddAttr)
    130 {
    131 
    132     pObjInfo->cbObject    = RTDvmVolumeGetSize(hVolume);
    133     pObjInfo->cbAllocated = pObjInfo->cbObject;
    134     RTTimeSpecSetNano(&pObjInfo->AccessTime, 0);
    135     RTTimeSpecSetNano(&pObjInfo->ModificationTime, 0);
    136     RTTimeSpecSetNano(&pObjInfo->ChangeTime, 0);
    137     RTTimeSpecSetNano(&pObjInfo->BirthTime, 0);
    138     pObjInfo->Attr.fMode = RTFS_TYPE_FILE | RTFS_DOS_NT_NORMAL;
    139     if (fReadOnly)
    140         pObjInfo->Attr.fMode |= RTFS_DOS_READONLY | 0444;
    141     else
    142         pObjInfo->Attr.fMode |= 0666;
    143 
     145 * Worker for rtDvmVfsFile_QueryInfoWorker and rtDvmVfsSym_QueryInfoWorker.
     146 */
     147static int rtDvmVfsFileSym_QueryAddAttrWorker(RTDVMVOLUME hVolume, RTDVM hVolMgr,
     148                                              PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAddAttr)
     149{
    144150    switch (enmAddAttr)
    145151    {
     
    187193    }
    188194    return VINF_SUCCESS;
     195}
     196
     197
     198/**
     199 * Worker for rtDvmVfsFile_QueryInfo, rtDvmVfsDir_QueryEntryInfo, and
     200 * rtDvmVfsDir_ReadDir.
     201 */
     202static int rtDvmVfsFile_QueryInfoWorker(RTDVMVOLUME hVolume, RTDVM hVolMgr, bool fReadOnly,
     203                                        PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAddAttr)
     204{
     205
     206    pObjInfo->cbObject    = RTDvmVolumeGetSize(hVolume);
     207    pObjInfo->cbAllocated = pObjInfo->cbObject;
     208    RTTimeSpecSetNano(&pObjInfo->AccessTime, 0);
     209    RTTimeSpecSetNano(&pObjInfo->ModificationTime, 0);
     210    RTTimeSpecSetNano(&pObjInfo->ChangeTime, 0);
     211    RTTimeSpecSetNano(&pObjInfo->BirthTime, 0);
     212    pObjInfo->Attr.fMode = RTFS_TYPE_FILE | RTFS_DOS_NT_NORMAL;
     213    if (fReadOnly)
     214        pObjInfo->Attr.fMode |= RTFS_DOS_READONLY | 0444;
     215    else
     216        pObjInfo->Attr.fMode |= 0666;
     217
     218    return rtDvmVfsFileSym_QueryAddAttrWorker(hVolume, hVolMgr, pObjInfo, enmAddAttr);
    189219}
    190220
     
    533563
    534564
     565/*********************************************************************************************************************************
     566*   DVM Symbolic Link Objects                                                                                                    *
     567*********************************************************************************************************************************/
     568/**
     569 * @interface_method_impl{RTVFSOBJOPS,pfnClose}
     570 */
     571static DECLCALLBACK(int) rtDvmVfsSym_Close(void *pvThis)
     572{
     573    PRTVFSDVMSYMLINK pThis = (PRTVFSDVMSYMLINK)pvThis;
     574    if (pThis->pszSymlink)
     575    {
     576        RTStrFree(pThis->pszSymlink);
     577        pThis->pszSymlink = NULL;
     578    }
     579    if (pThis->hVol != NIL_RTDVMVOLUME)
     580    {
     581        RTDvmVolumeRelease(pThis->hVol);
     582        pThis->hVol = NIL_RTDVMVOLUME;
     583    }
     584    if (pThis->hVolMgr != NIL_RTDVM)
     585    {
     586        RTDvmRelease(pThis->hVolMgr);
     587        pThis->hVolMgr = NIL_RTDVM;
     588    }
     589    return VINF_SUCCESS;
     590}
     591
     592
     593/**
     594 * Worker for rtDvmVfsSym_QueryInfo and rtDvmVfsDir_Read.
     595 *
     596 * @returns IPRT status code.
     597 * @param   hVolume             The volume handle.
     598 * @param   hVolMgr             The volume manager handle. Optional.
     599 * @param   pszTarget           The link target.
     600 * @param   pObjInfo            The object info structure to populate.
     601 * @param   enmAddAttr          The additional attributes to supply.
     602 */
     603static int rtDvmVfsSym_QueryInfoWorker(RTDVMVOLUME hVolume, RTDVM hVolMgr, const char *pszTarget,
     604                                       PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAddAttr)
     605{
     606    RT_ZERO(*pObjInfo);
     607    pObjInfo->cbObject = pObjInfo->cbAllocated = pszTarget ? strlen(pszTarget) : 0;
     608    pObjInfo->Attr.fMode = 0777 | RTFS_TYPE_SYMLINK | RTFS_DOS_NT_REPARSE_POINT;
     609
     610    return rtDvmVfsFileSym_QueryAddAttrWorker(hVolume, hVolMgr, pObjInfo, enmAddAttr);
     611}
     612
     613
     614/**
     615 * @interface_method_impl{RTVFSOBJOPS,pfnQueryInfo}
     616 */
     617static DECLCALLBACK(int) rtDvmVfsSym_QueryInfo(void *pvThis, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAddAttr)
     618{
     619    PRTVFSDVMSYMLINK pThis = (PRTVFSDVMSYMLINK)pvThis;
     620    return rtDvmVfsSym_QueryInfoWorker(pThis->hVol, pThis->hVolMgr, pThis->szTarget, pObjInfo, enmAddAttr);
     621}
     622
     623
     624/**
     625 * @interface_method_impl{RTVFSSYMLINKOPS,pfnRead}
     626 */
     627static DECLCALLBACK(int) rtDvmVfsSym_Read(void *pvThis, char *pszTarget, size_t cbTarget)
     628{
     629    PRTVFSDVMSYMLINK pThis = (PRTVFSDVMSYMLINK)pvThis;
     630    return RTStrCopy(pszTarget, cbTarget, pThis->szTarget);
     631}
     632
     633
     634/**
     635 * DVM symbolic link operations.
     636 */
     637static const RTVFSSYMLINKOPS g_rtDvmVfsSymOps =
     638{
     639    { /* Obj */
     640        RTVFSOBJOPS_VERSION,
     641        RTVFSOBJTYPE_SYMLINK,
     642        "DvmSymlink",
     643        rtDvmVfsSym_Close,
     644        rtDvmVfsSym_QueryInfo,
     645        RTVFSOBJOPS_VERSION
     646    },
     647    RTVFSSYMLINKOPS_VERSION,
     648    0,
     649    { /* ObjSet */
     650        RTVFSOBJSETOPS_VERSION,
     651        RT_UOFFSETOF(RTVFSSYMLINKOPS, ObjSet) - RT_UOFFSETOF(RTVFSSYMLINKOPS, Obj),
     652        NULL /*rtDvmVfsSym_SetMode*/,
     653        NULL /*rtDvmVfsSym_SetTimes*/,
     654        NULL /*rtDvmVfsSym_SetOwner*/,
     655        RTVFSOBJSETOPS_VERSION
     656    },
     657    rtDvmVfsSym_Read,
     658    RTVFSSYMLINKOPS_VERSION
     659};
     660
     661
     662/**
     663 * Internal worker for rtDvmVfsDir_OpenFile.
     664 *
     665 * @returns IPRT status code.
     666 * @param   hVol                The volume handle (not consumed).
     667 * @param   hVolMgr             The volume manager handle (not consumed).
     668 * @param   iVol                The volume number.
     669 * @param   pszSymlink          The volume name. Consumed on success.
     670 * @param   phVfsSymlinkOut     Where to return the handle to the file.
     671 */
     672static int rtDvmVfsCreateSymlinkForVolume(RTDVMVOLUME hVol, RTDVM hVolMgr, uint32_t iVol, char *pszSymlink,
     673                                          PRTVFSSYMLINK phVfsSymlinkOut)
     674{
     675    uint32_t cRefs = RTDvmVolumeRetain(hVol);
     676    AssertReturn(cRefs != UINT32_MAX, VERR_INVALID_HANDLE);
     677
     678    cRefs = RTDvmRetain(hVolMgr);
     679    AssertReturnStmt(cRefs != UINT32_MAX, RTDvmVolumeRelease(hVol), VERR_INVALID_HANDLE);
     680
     681    /*
     682     * Create the symlink.
     683     */
     684    RTVFSSYMLINK        hVfsSym;
     685    PRTVFSDVMSYMLINK    pThis;
     686    int rc = RTVfsNewSymlink(&g_rtDvmVfsSymOps, sizeof(*pThis), NIL_RTVFS, NIL_RTVFSLOCK, &hVfsSym, (void **)&pThis);
     687    if (RT_SUCCESS(rc))
     688    {
     689        pThis->hVol       = hVol;
     690        pThis->hVolMgr    = hVolMgr;
     691        pThis->pszSymlink = pszSymlink;
     692        RTStrPrintf(pThis->szTarget, sizeof(pThis->szTarget), "vol%u", iVol);
     693
     694        *phVfsSymlinkOut = hVfsSym;
     695        return VINF_SUCCESS;
     696    }
     697    RTDvmRelease(hVolMgr);
     698    RTDvmVolumeRelease(hVol);
     699    return rc;
     700}
     701
     702
     703
     704/*********************************************************************************************************************************
     705*   DVM Directory Objects                                                                                                        *
     706*********************************************************************************************************************************/
     707
    535708/**
    536709 * @interface_method_impl{RTVFSOBJOPS,pfnClose}
     
    544717        RTDvmVolumeRelease(pThis->hCurVolume);
    545718        pThis->hCurVolume = NIL_RTDVMVOLUME;
     719    }
     720
     721    if (pThis->pszNameAlias)
     722    {
     723        RTStrFree(pThis->pszNameAlias);
     724        pThis->pszNameAlias = NULL;
    546725    }
    547726
     
    637816
    638817
    639 static int rtDvmVfsDir_FindEntry(PRTDVMVFSDIR pThis, const char *pszEntry, PRTDVMVOLUME phVolume)
    640 {
     818static int rtDvmVfsDir_FindEntry(PRTDVMVFSDIR pThis, const char *pszEntry,
     819                                 PRTDVMVOLUME phVolume, uint32_t *piVol, char **ppszSymlink)
     820{
     821    *phVolume    = NIL_RTDVMVOLUME;
     822    *ppszSymlink = NULL;
     823    *piVol       = UINT32_MAX;
     824
    641825    /*
    642826     * Enumerate the volumes and try match the volume name.
     
    659843            {
    660844                fMatch = RTStrCmp(pszEntry, pszVolName) == 0 && *pszVolName != '\0';
     845                if (fMatch)
     846                {
     847                    *phVolume    = hVol;
     848                    *ppszSymlink = pszVolName;
     849                    *piVol       = iVol;
     850                    return VINF_SUCCESS;
     851                }
    661852                RTStrFree(pszVolName);
    662853            }
     
    680871            {
    681872                *phVolume = hVol;
     873                *piVol    = iVol;
    682874                return VINF_SUCCESS;
    683875            }
     
    744936     * Open volume file.
    745937     */
    746     RTDVMVOLUME hVolume = NIL_RTDVMVOLUME;
    747     int rc = rtDvmVfsDir_FindEntry(pThis, pszEntry, &hVolume);
     938    RTDVMVOLUME hVolume    = NIL_RTDVMVOLUME;
     939    uint32_t    iVol       = 0;
     940    char       *pszSymlink = NULL;
     941    int rc = rtDvmVfsDir_FindEntry(pThis, pszEntry, &hVolume, &iVol, &pszSymlink);
    748942    if (RT_SUCCESS(rc))
    749943    {
     
    754948            if (fFlags & (RTVFSOBJ_F_OPEN_FILE | RTVFSOBJ_F_OPEN_DEV_BLOCK))
    755949            {
    756                 if (   !(fOpen & RTFILE_O_WRITE)
    757                     || !pThis->pVfsVol->fReadOnly)
     950                if (!pszSymlink)
    758951                {
    759                     RTVFSFILE hVfsFile;
    760                     rc = rtDvmVfsCreateFileForVolume(pThis->pVfsVol, hVolume, fOpen, &hVfsFile);
    761                     if (RT_SUCCESS(rc))
     952                    if (   !(fOpen & RTFILE_O_WRITE)
     953                        || !pThis->pVfsVol->fReadOnly)
    762954                    {
    763                         *phVfsObj = RTVfsObjFromFile(hVfsFile);
    764                         RTVfsFileRelease(hVfsFile);
    765                         AssertStmt(*phVfsObj != NIL_RTVFSOBJ, rc = VERR_INTERNAL_ERROR_3);
     955                        /* Create file object. */
     956                        RTVFSFILE hVfsFile;
     957                        rc = rtDvmVfsCreateFileForVolume(pThis->pVfsVol, hVolume, fOpen, &hVfsFile);
     958                        if (RT_SUCCESS(rc))
     959                        {
     960                            *phVfsObj = RTVfsObjFromFile(hVfsFile);
     961                            RTVfsFileRelease(hVfsFile);
     962                            AssertStmt(*phVfsObj != NIL_RTVFSOBJ, rc = VERR_INTERNAL_ERROR_3);
     963                        }
    766964                    }
     965                    else
     966                        rc = VERR_WRITE_PROTECT;
    767967                }
    768968                else
    769                     rc = VERR_WRITE_PROTECT;
     969                    rc = VERR_IS_A_SYMLINK;
     970            }
     971            else if (fFlags & RTVFSOBJ_F_OPEN_SYMLINK)
     972            {
     973                /* Create symlink object */
     974                RTVFSSYMLINK hVfsSym;
     975                rc = rtDvmVfsCreateSymlinkForVolume(hVolume, pThis->pVfsVol ? pThis->pVfsVol->hVolMgr : NIL_RTDVM, iVol,
     976                                                    pszSymlink, &hVfsSym);
     977                if (RT_SUCCESS(rc))
     978                {
     979                    *phVfsObj = RTVfsObjFromSymlink(hVfsSym);
     980                    RTVfsSymlinkRelease(hVfsSym);
     981                    AssertStmt(*phVfsObj != NIL_RTVFSOBJ, rc = VERR_INTERNAL_ERROR_3);
     982                    pszSymlink = NULL;
     983                }
    770984            }
    771985            else
     
    775989            rc = VERR_ALREADY_EXISTS;
    776990        RTDvmVolumeRelease(hVolume);
     991        if (pszSymlink)
     992            RTStrFree(pszSymlink);
    777993    }
    778994    return rc;
     
    8611077    pThis->fReturnCurrent = false;
    8621078    pThis->offDir         = 0;
     1079    if (pThis->pszNameAlias)
     1080    {
     1081        RTStrFree(pThis->pszNameAlias);
     1082        pThis->pszNameAlias = NULL;
     1083    }
    8631084
    8641085    return VINF_SUCCESS;
     
    8771098
    8781099    /*
    879      * Get the volume to return info about.
    880      */
     1100     * Format the volume name since we'll be needing it all but the final call.
     1101     */
     1102    char         szVolNo[16];
     1103    size_t const cchVolNo = RTStrPrintf(szVolNo, sizeof(szVolNo), "vol%u", pThis->offDir);
     1104
    8811105    if (!pThis->fReturnCurrent)
    8821106    {
     1107        /*
     1108         * Do we have a pending name alias to return?
     1109         */
     1110        if (pThis->pszNameAlias)
     1111        {
     1112            size_t cchNameAlias = strlen(pThis->pszNameAlias);
     1113            size_t cbNeeded     = RT_UOFFSETOF_DYN(RTDIRENTRYEX, szName[cchNameAlias + 1]);
     1114            if (cbNeeded <= *pcbDirEntry)
     1115            {
     1116                *pcbDirEntry = cbNeeded;
     1117
     1118                /* Do the names. */
     1119                pDirEntry->cbName = (uint16_t)cchNameAlias;
     1120                memcpy(pDirEntry->szName, pThis->pszNameAlias, cchNameAlias + 1);
     1121                pDirEntry->cwcShortName = 0;
     1122                pDirEntry->wszShortName[0] = '\0';
     1123
     1124
     1125                /* Do the rest. */
     1126                rc = rtDvmVfsSym_QueryInfoWorker(pThis->hCurVolume, pVfsVol->hVolMgr, szVolNo, &pDirEntry->Info, enmAddAttr);
     1127                if (RT_SUCCESS(rc))
     1128                {
     1129                    RTStrFree(pThis->pszNameAlias);
     1130                    pThis->pszNameAlias = NULL;
     1131                    pThis->offDir      += 1;
     1132                }
     1133                return rc;
     1134            }
     1135
     1136            *pcbDirEntry = cbNeeded;
     1137            return VERR_BUFFER_OVERFLOW;
     1138        }
     1139
     1140        /*
     1141         * Get the next volume to return info about.
     1142         */
    8831143        if (pThis->offDir < pVfsVol->cVolumes)
    8841144        {
     
    8921152            RTDvmVolumeRelease(pThis->hCurVolume);
    8931153            pThis->hCurVolume = hNextVolume;
     1154
     1155            /* Check if we need to return a name alias later. */
     1156            rc = RTDvmVolumeQueryName(pThis->hCurVolume, &pThis->pszNameAlias);
     1157            if (RT_FAILURE(rc))
     1158                pThis->pszNameAlias = NULL;
     1159            else if (*pThis->pszNameAlias == '\0')
     1160            {
     1161                RTStrFree(pThis->pszNameAlias);
     1162                pThis->pszNameAlias = NULL;
     1163            }
    8941164        }
    8951165        else
     
    9041174     * Figure out the name length.
    9051175     */
    906     char szVolNo[16];
    907     RTStrPrintf(szVolNo, sizeof(szVolNo), "vol%u", pThis->offDir);
    908 
    909     char *pszVolName;
    910     rc = RTDvmVolumeQueryName(pThis->hCurVolume, &pszVolName);
    911     if (   RT_SUCCESS(rc)
    912         || rc == VERR_NOT_SUPPORTED)
    913     {
    914         if (rc == VERR_NOT_SUPPORTED)
    915             pszVolName = szVolNo;
    916         else if (*pszVolName == '\0')
     1176    size_t cbNeeded = RT_UOFFSETOF_DYN(RTDIRENTRYEX, szName[cchVolNo + 1]);
     1177    if (cbNeeded <= *pcbDirEntry)
     1178    {
     1179        *pcbDirEntry = cbNeeded;
     1180
     1181        /* Do the names. */
     1182        pDirEntry->cbName = (uint16_t)cchVolNo;
     1183        memcpy(pDirEntry->szName, szVolNo, cchVolNo + 1);
     1184        pDirEntry->cwcShortName = 0;
     1185        pDirEntry->wszShortName[0] = '\0';
     1186
     1187        /* Do the rest. */
     1188        rc = rtDvmVfsFile_QueryInfoWorker(pThis->hCurVolume, pVfsVol->hVolMgr, pVfsVol->fReadOnly, &pDirEntry->Info, enmAddAttr);
     1189        if (RT_SUCCESS(rc))
    9171190        {
    918             RTStrFree(pszVolName);
    919             pszVolName = szVolNo;
    920         }
    921 
    922         size_t cchVolName = strlen(pszVolName);
    923         size_t cbNeeded   = RT_UOFFSETOF_DYN(RTDIRENTRYEX,  szName[cchVolName + 1]);
    924         if (cbNeeded <= *pcbDirEntry)
    925         {
    926             *pcbDirEntry = cbNeeded;
    927 
    928             /* Do the names. */
    929             pDirEntry->cbName = (uint16_t)cchVolName;
    930             memcpy(pDirEntry->szName, pszVolName, cchVolName + 1);
    931             if (pszVolName != szVolNo)
    932             {
    933                 RTStrFree(pszVolName);
    934 
    935                 PRTUTF16 pwszShortName = pDirEntry->wszShortName;
    936                 size_t   cwcShortName = 0;
    937                 rc = RTStrToUtf16Ex(szVolNo, RTSTR_MAX, &pwszShortName, RT_ELEMENTS(pDirEntry->wszShortName), &cwcShortName);
    938                 AssertRC(rc);
    939                 pDirEntry->cwcShortName = (uint16_t)cwcShortName;
    940             }
    941             else
    942             {
    943                 pDirEntry->cwcShortName = 0;
    944                 pDirEntry->wszShortName[0] = '\0';
    945             }
    946 
    947             /* Do the rest. */
    948             rc = rtDvmVfsFile_QueryInfoWorker(pThis->hCurVolume, pVfsVol->hVolMgr, pVfsVol->fReadOnly,
    949                                               &pDirEntry->Info, enmAddAttr);
    950             pThis->fReturnCurrent = !RT_SUCCESS(rc);
    951             pThis->offDir        += RT_SUCCESS(rc);
     1191            pThis->fReturnCurrent = false;
     1192            if (!pThis->pszNameAlias)
     1193                pThis->offDir += 1;
    9521194            return rc;
    9531195        }
    954 
     1196    }
     1197    else
     1198    {
    9551199        *pcbDirEntry = cbNeeded;
    9561200        rc = VERR_BUFFER_OVERFLOW;
    957 
    958         if (pszVolName != szVolNo)
    959             RTStrFree(pszVolName);
    960     }
    961 
     1201    }
    9621202    pThis->fReturnCurrent = true;
    9631203    return rc;
     
    10471287        pNewDir->pVfsVol        = pThis;
    10481288        pNewDir->fReturnCurrent = false;
     1289        pNewDir->pszNameAlias   = NULL;
    10491290        pNewDir->hCurVolume     = NIL_RTDVMVOLUME;
    10501291    }
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