VirtualBox

Changeset 75380 in vbox


Ignore:
Timestamp:
Nov 9, 2018 10:25:30 PM (7 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
126515
Message:

Main,VBoxManage,FE/Qt: Extended the createSharedFolder and ISharedFolder methods with a mount poit parameter/attribute for use when auto-mounting. This is especially useful for Windows and OS/2 guests which operates with drive letters. The change has not yet trickled down to the guest interface and VBoxService.

Location:
trunk
Files:
23 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/settings.h

    r75361 r75380  
    751751    bool            fWritable;
    752752    bool            fAutoMount;
     753    com::Utf8Str    strAutoMountPoint;
    753754};
    754755
  • trunk/include/VBox/shflsvc.h

    r75333 r75380  
    4040#include <iprt/fs.h>
    4141#include <iprt/assert.h>
     42#ifdef IN_RING3
     43# include <iprt/mem.h>
     44#endif
    4245
    4346
     
    231234
    232235/**
     236 * Helper for copying one string into another.
     237 *
     238 * @returns pDst
     239 * @param   pDst        The destination string. Assumed to be the same size as
     240 *                      the source.
     241 * @param   pSrc        The source string.
     242 */
     243DECLINLINE(PSHFLSTRING) ShflStringCopy(PSHFLSTRING pDst, PCSHFLSTRING pSrc)
     244{
     245    pDst->u16Length = pSrc->u16Length;
     246    pDst->u16Size   = pSrc->u16Size;
     247    memcpy(&pDst->String, &pSrc->String, pSrc->u16Size);
     248    return pDst;
     249}
     250
     251#ifdef IN_RING3
     252
     253/**
     254 * Duplicates a string using RTMemAlloc as allocator.
     255 *
     256 * @returns Copy, NULL if out of memory.
     257 * @param   pSrc        The source string.
     258 */
     259DECLINLINE(PSHFLSTRING) ShflStringDup(PCSHFLSTRING pSrc)
     260{
     261    PSHFLSTRING pDst = (PSHFLSTRING)RTMemAlloc(SHFLSTRING_HEADER_SIZE + pSrc->u16Size);
     262    if (pDst)
     263        return ShflStringCopy(pDst, pSrc);
     264    return pDst;
     265}
     266
     267/**
     268 * Duplicates a UTF-16 string using RTMemAlloc as allocator.
     269 *
     270 * The returned string will be using UTF-16 encoding too.
     271 *
     272 * @returns Pointer to copy on success - pass to RTMemFree to free.
     273 *          NULL if out of memory.
     274 * @param   pwszSrc     The source string.  Encoding is not checked.
     275 */
     276DECLINLINE(PSHFLSTRING) ShflStringDupUtf16(PCRTUTF16 pwszSrc)
     277{
     278    size_t cwcSrc = RTUtf16Len(pwszSrc);
     279    if (cwcSrc < UINT16_MAX / sizeof(RTUTF16))
     280    {
     281        PSHFLSTRING pDst = (PSHFLSTRING)RTMemAlloc(SHFLSTRING_HEADER_SIZE + (cwcSrc + 1) * sizeof(RTUTF16));
     282        if (pDst)
     283        {
     284            pDst->u16Length = (uint16_t)(cwcSrc * sizeof(RTUTF16));
     285            pDst->u16Size   = (uint16_t)((cwcSrc + 1) * sizeof(RTUTF16));
     286            memcpy(&pDst->String, pwszSrc, (cwcSrc + 1) * sizeof(RTUTF16));
     287            return pDst;
     288        }
     289    }
     290    AssertFailed();
     291    return NULL;
     292}
     293
     294/**
     295 * Duplicates a UTF-8 string using RTMemAlloc as allocator.
     296 *
     297 * The returned string will be using UTF-8 encoding too.
     298 *
     299 * @returns Pointer to copy on success - pass to RTMemFree to free.
     300 *          NULL if out of memory.
     301 * @param   pszSrc      The source string.  Encoding is not checked.
     302 */
     303DECLINLINE(PSHFLSTRING) ShflStringDupUtf8(const char *pszSrc)
     304{
     305    size_t cchSrc = strlen(pszSrc);
     306    if (cchSrc < UINT16_MAX)
     307    {
     308        PSHFLSTRING pDst = (PSHFLSTRING)RTMemAlloc(SHFLSTRING_HEADER_SIZE + cchSrc + 1);
     309        if (pDst)
     310        {
     311            pDst->u16Length = (uint16_t)cchSrc;
     312            pDst->u16Size   = (uint16_t)(cchSrc + 1);
     313            memcpy(&pDst->String, pszSrc, cchSrc + 1);
     314            return pDst;
     315        }
     316    }
     317    AssertFailed();
     318    return NULL;
     319}
     320
     321/**
     322 * Creates a UTF-16 duplicate of the UTF-8 string @a pszSrc using RTMemAlloc as
     323 * allocator.
     324 *
     325 * @returns Pointer to copy on success - pass to RTMemFree to free.
     326 *          NULL if out of memory or invalid UTF-8 encoding.
     327 * @param   pszSrc      The source string.
     328 */
     329DECLINLINE(PSHFLSTRING) ShflStringDupUtf8AsUtf16(const char *pszSrc)
     330{
     331    size_t cwcConversion = 0;
     332    int rc = RTStrCalcUtf16LenEx(pszSrc, RTSTR_MAX, &cwcConversion);
     333    if (   RT_SUCCESS(rc)
     334        && cwcConversion < UINT16_MAX / sizeof(RTUTF16))
     335    {
     336        PSHFLSTRING pDst = (PSHFLSTRING)RTMemAlloc(SHFLSTRING_HEADER_SIZE + (cwcConversion + 1) * sizeof(RTUTF16));
     337        if (pDst)
     338        {
     339            PRTUTF16 pwszDst = pDst->String.ucs2;
     340            pDst->u16Size = (uint16_t)((cwcConversion + 1) * sizeof(RTUTF16));
     341            rc = RTStrToUtf16Ex(pszSrc, RTSTR_MAX, &pwszDst, cwcConversion + 1, &cwcConversion);
     342            AssertRC(rc);
     343            if (RT_SUCCESS(rc))
     344            {
     345                pDst->u16Length = (uint16_t)(cwcConversion * sizeof(RTUTF16));
     346                return pDst;
     347            }
     348            RTMemFree(pDst);
     349        }
     350    }
     351    AssertMsgFailed(("rc=%Rrc cwcConversion=%#x\n", rc, cwcConversion));
     352    return NULL;
     353}
     354
     355#endif /* IN_RING3 */
     356
     357/**
    233358 * Validates a HGCM string output parameter.
    234359 *
     
    312437}
    313438
     439/** Macro for passing as string as a HGCM parmeter (pointer)  */
     440#define SHFLSTRING_TO_HGMC_PARAM(a_pParam, a_pString) \
     441    do { \
     442        (a_pParam)->type = VBOX_HGCM_SVC_PARM_PTR; \
     443        (a_pParam)->u.pointer.addr = (a_pString); \
     444        (a_pParam)->u.pointer.size = ShflStringSizeOfBuffer(a_pString); \
     445    } while (0)
     446
    314447/** @} */
    315448
     
    14261559#define SHFL_ADD_MAPPING_F_MISSING          (RT_BIT_32(3))
    14271560
    1428 #define SHFL_CPARMS_ADD_MAPPING  (3)
     1561#define SHFL_CPARMS_ADD_MAPPING  (4)
    14291562
    14301563/**
  • trunk/src/VBox/Frontends/VBoxManage/VBoxManageInfo.cpp

    r75361 r75380  
    4949// funcs
    5050///////////////////////////////////////////////////////////////////////////////
     51
     52/**
     53 * Helper for formatting an indexed name or some such thing.
     54 */
     55static const char *FmtNm(char psz[80], const char *pszFormat, ...)
     56{
     57    va_list va;
     58    va_start(va, pszFormat);
     59    RTStrPrintfV(psz, 80, pszFormat, va);
     60    va_end(va);
     61    return psz;
     62}
    5163
    5264HRESULT showSnapshots(ComPtr<ISnapshot> &rootSnapshot,
     
    368380}
    369381
     382/** Shows a shared folder.   */
     383static HRESULT showSharedFolder(ComPtr<ISharedFolder> &sf, VMINFO_DETAILS details, const char *pszDesc,
     384                                const char *pszMrInfix, size_t idxMr, bool fFirst)
     385{
     386    Bstr name, hostPath, bstrAutoMountPoint;
     387    BOOL writable = FALSE, fAutoMount = FALSE;
     388    CHECK_ERROR2I_RET(sf, COMGETTER(Name)(name.asOutParam()), hrcCheck);
     389    CHECK_ERROR2I_RET(sf, COMGETTER(HostPath)(hostPath.asOutParam()), hrcCheck);
     390    CHECK_ERROR2I_RET(sf, COMGETTER(Writable)(&writable), hrcCheck);
     391    CHECK_ERROR2I_RET(sf, COMGETTER(AutoMount)(&fAutoMount), hrcCheck);
     392    CHECK_ERROR2I_RET(sf, COMGETTER(AutoMountPoint)(bstrAutoMountPoint.asOutParam()), hrcCheck);
     393
     394    if (fFirst && details != VMINFO_MACHINEREADABLE)
     395        RTPrintf("\n\n");
     396    if (details == VMINFO_MACHINEREADABLE)
     397    {
     398        char szNm[80];
     399        outputMachineReadableString(FmtNm(szNm, "SharedFolderName%s%zu", pszMrInfix, idxMr), &name);
     400        outputMachineReadableString(FmtNm(szNm, "SharedFolderPath%s%zu", pszMrInfix, idxMr), &hostPath);
     401    }
     402    else
     403    {
     404        RTPrintf("Name: '%ls', Host path: '%ls' (%s), %s%s%",
     405                 name.raw(), hostPath.raw(), pszDesc, writable ? "writable" : "readonly", fAutoMount ? ", auto-mount" : "");
     406        if (bstrAutoMountPoint.isNotEmpty())
     407            RTPrintf(", mount-point: '%ls'\n", bstrAutoMountPoint.raw());
     408        else
     409            RTPrintf("\n");
     410    }
     411    return S_OK;
     412}
     413
     414
    370415static const char *paravirtProviderToString(ParavirtProvider_T provider, VMINFO_DETAILS details)
    371416{
     
    407452            return "Unknown";
    408453    }
    409 }
    410 
    411 /**
    412  * Helper for formatting an indexed name or some such thing.
    413  */
    414 static const char *FmtNm(char psz[80], const char *pszFormat, ...)
    415 {
    416     va_list va;
    417     va_start(va, pszFormat);
    418     RTStrPrintfV(psz, 80, pszFormat, va);
    419     va_end(va);
    420     return psz;
    421454}
    422455
     
    22182251        {
    22192252            ComPtr<ISharedFolder> sf = sfColl[i];
    2220             Bstr name, hostPath;
    2221             sf->COMGETTER(Name)(name.asOutParam());
    2222             sf->COMGETTER(HostPath)(hostPath.asOutParam());
    2223             RTPrintf("Name: '%ls', Host path: '%ls' (global mapping)\n", name.raw(), hostPath.raw());
     2253            showSharedFolder(sf, details, "global mapping", "GlobalMapping", i + 1, numSharedFolders == 0);
    22242254            ++numSharedFolders;
    22252255        }
     
    22292259    {
    22302260        com::SafeIfaceArray <ISharedFolder> folders;
    2231 
    22322261        CHECK_ERROR_RET(machine, COMGETTER(SharedFolders)(ComSafeArrayAsOutParam(folders)), rc);
    2233 
    22342262        for (size_t i = 0; i < folders.size(); ++i)
    22352263        {
    22362264            ComPtr<ISharedFolder> sf = folders[i];
    2237 
    2238             Bstr name, hostPath;
    2239             BOOL writable;
    2240             sf->COMGETTER(Name)(name.asOutParam());
    2241             sf->COMGETTER(HostPath)(hostPath.asOutParam());
    2242             sf->COMGETTER(Writable)(&writable);
    2243             if (!numSharedFolders && details != VMINFO_MACHINEREADABLE)
    2244                 RTPrintf("\n\n");
    2245             if (details == VMINFO_MACHINEREADABLE)
    2246             {
    2247                 outputMachineReadableString(FmtNm(szNm, "SharedFolderNameMachineMapping%zu", i + 1), &name);
    2248                 outputMachineReadableString(FmtNm(szNm, "SharedFolderPathMachineMapping%zu", i + 1), &hostPath);
    2249             }
    2250             else
    2251                 RTPrintf("Name: '%ls', Host path: '%ls' (machine mapping), %s\n",
    2252                          name.raw(), hostPath.raw(), writable ? "writable" : "readonly");
     2265            showSharedFolder(sf, details, "machine mapping", "MachineMapping", i + 1, numSharedFolders == 0);
    22532266            ++numSharedFolders;
    22542267        }
     
    22582271    {
    22592272        com::SafeIfaceArray <ISharedFolder> folders;
    2260 
    22612273        CHECK_ERROR_RET(pConsole, COMGETTER(SharedFolders)(ComSafeArrayAsOutParam(folders)), rc);
    2262 
    22632274        for (size_t i = 0; i < folders.size(); ++i)
    22642275        {
    22652276            ComPtr<ISharedFolder> sf = folders[i];
    2266 
    2267             Bstr name, hostPath;
    2268             sf->COMGETTER(Name)(name.asOutParam());
    2269             sf->COMGETTER(HostPath)(hostPath.asOutParam());
    2270             if (!numSharedFolders && details != VMINFO_MACHINEREADABLE)
    2271                 RTPrintf("\n\n");
    2272             if (details == VMINFO_MACHINEREADABLE)
    2273             {
    2274                 outputMachineReadableString(FmtNm(szNm, "SharedFolderNameTransientMapping%zu", i + 1), &name);
    2275                 outputMachineReadableString(FmtNm(szNm, "SharedFolderPathTransientMapping%zu", i + 1), &hostPath);
    2276             }
    2277             else
    2278                 RTPrintf("Name: '%ls', Host path: '%ls' (transient mapping)\n", name.raw(), hostPath.raw());
     2277            showSharedFolder(sf, details, "transient mapping", "TransientMapping", i + 1, numSharedFolders == 0);
    22792278            ++numSharedFolders;
    22802279        }
  • trunk/src/VBox/Frontends/VBoxManage/VBoxManageMisc.cpp

    r74431 r75380  
    10961096        bool fWritable = true;
    10971097        bool fAutoMount = false;
     1098        char *pszAutoMountPoint = "";
    10981099
    10991100        for (int i = 2; i < a->argc; i++)
     
    11301131                fAutoMount = true;
    11311132            }
     1133            else if (!strcmp(a->argv[i], "--auto-mount-point"))
     1134            {
     1135                if (a->argc <= i + 1 || !*a->argv[i+1])
     1136                    return errorArgument("Missing argument to '%s'", a->argv[i]);
     1137                i++;
     1138                pszAutoMountPoint = a->argv[i];
     1139            }
    11321140            else
    11331141                return errorSyntax(USAGE_SHAREDFOLDER_ADD, "Invalid parameter '%s'", Utf8Str(a->argv[i]).c_str());
     
    11601168                                      "Machine '%s' is not currently running.\n", pszMachineName);
    11611169
    1162             CHECK_ERROR(console, CreateSharedFolder(Bstr(name).raw(),
    1163                                                     Bstr(hostpath).raw(),
    1164                                                     fWritable, fAutoMount));
     1170            CHECK_ERROR(console, CreateSharedFolder(Bstr(name).raw(), Bstr(hostpath).raw(),
     1171                                                    fWritable, fAutoMount, Bstr(pszAutoMountPoint).raw()));
    11651172            a->session->UnlockMachine();
    11661173        }
     
    11741181            a->session->COMGETTER(Machine)(sessionMachine.asOutParam());
    11751182
    1176             CHECK_ERROR(sessionMachine, CreateSharedFolder(Bstr(name).raw(),
    1177                                                            Bstr(hostpath).raw(),
    1178                                                            fWritable, fAutoMount));
     1183            CHECK_ERROR(sessionMachine, CreateSharedFolder(Bstr(name).raw(), Bstr(hostpath).raw(),
     1184                                                           fWritable, fAutoMount, Bstr(pszAutoMountPoint).raw()));
    11791185            if (SUCCEEDED(rc))
    11801186                CHECK_ERROR(sessionMachine, SaveSettings());
  • trunk/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsSF.cpp

    r71355 r75380  
    4242    UIDataSettingsSharedFolder()
    4343        : m_enmType(MachineType)
    44         , m_strName(QString())
    45         , m_strPath(QString())
     44        , m_strName()
     45        , m_strPath()
     46        , m_fWritable(false)
    4647        , m_fAutoMount(false)
    47         , m_fWritable(false)
     48        , m_strAutoMountPoint()
    4849    {}
    4950
     
    5253    {
    5354        return true
    54                && (m_enmType == other.m_enmType)
    55                && (m_strName == other.m_strName)
    56                && (m_strPath == other.m_strPath)
    57                && (m_fAutoMount == other.m_fAutoMount)
    58                && (m_fWritable == other.m_fWritable)
     55               && m_enmType == other.m_enmType
     56               && m_strName == other.m_strName
     57               && m_strPath == other.m_strPath
     58               && m_fWritable == other.m_fWritable
     59               && m_fAutoMount == other.m_fAutoMount
     60               && m_strAutoMountPoint == other.m_strAutoMountPoint
    5961               ;
    6062    }
     
    7173    /** Holds the shared folder path. */
    7274    QString             m_strPath;
     75    /** Holds whether the shared folder should be writeable. */
     76    bool                m_fWritable;
    7377    /** Holds whether the shared folder should be auto-mounted at startup. */
    7478    bool                m_fAutoMount;
    75     /** Holds whether the shared folder should be writeable. */
    76     bool                m_fWritable;
     79    /** Where in the guest to try auto mount the shared folder (drive for
     80     * Windows & OS/2, path for unixy guests). */
     81    QString             m_strAutoMountPoint;
    7782};
    7883
     
    161166            m_fields << m_strName
    162167                     << m_strPath
     168                     << (m_fWritable ? UIMachineSettingsSF::tr("Full") : UIMachineSettingsSF::tr("Read-only"))
    163169                     << (m_fAutoMount ? UIMachineSettingsSF::tr("Yes") : "")
    164                      << (m_fWritable ? UIMachineSettingsSF::tr("Full") : UIMachineSettingsSF::tr("Read-only"));
     170                     << m_strAutoMountPoint;
    165171
    166172        /* Adjust item layout: */
     
    180186    virtual QString defaultText() const /* override */
    181187    {
    182         return parentItem() ?
    183                tr("%1, %2: %3, %4: %5, %6: %7",
    184                   "col.1 text, col.2 name: col.2 text, col.3 name: col.3 text, col.4 name: col.4 text")
     188        return parentItem()
     189             ? tr("%1, %2: %3, %4: %5, %6: %7, %8: %9",
     190                  "col.1 text, col.2 name: col.2 text, col.3 name: col.3 text, col.4 name: col.4 text, col.5 name: col.5 text")
    185191                  .arg(text(0))
    186192                  .arg(parentTree()->headerItem()->text(1)).arg(text(1))
    187193                  .arg(parentTree()->headerItem()->text(2)).arg(text(2))
    188                   .arg(parentTree()->headerItem()->text(3)).arg(text(3)) :
    189                text(0);
     194                  .arg(parentTree()->headerItem()->text(3)).arg(text(3))
     195                  .arg(parentTree()->headerItem()->text(4)).arg(text(4))
     196             : text(0);
    190197    }
    191198
     
    215222            iTextWidth = fm.width(strOneString);
    216223            if (   iTextWidth
    217                 && (iTextWidth + iIndentSize > cWidth))
     224                && iTextWidth + iIndentSize > cWidth)
    218225            {
    219226                iStart = 0;
     
    331338                oldFolderData.m_strName = comFolder.GetName();
    332339                oldFolderData.m_strPath = comFolder.GetHostPath();
     340                oldFolderData.m_fWritable = comFolder.GetWritable();
    333341                oldFolderData.m_fAutoMount = comFolder.GetAutoMount();
    334                 oldFolderData.m_fWritable = comFolder.GetWritable();
     342                oldFolderData.m_strAutoMountPoint = comFolder.GetAutoMountPoint();
    335343                /* Override folder cache key: */
    336344                strFolderKey = oldFolderData.m_strName;
     
    474482        newFolderData.m_strName = strName;
    475483        newFolderData.m_strPath = strPath;
     484        newFolderData.m_fWritable = dlgFolderDetails.isWriteable();
    476485        newFolderData.m_fAutoMount = dlgFolderDetails.isAutoMounted();
    477         newFolderData.m_fWritable = dlgFolderDetails.isWriteable();
     486        newFolderData.m_strAutoMountPoint = dlgFolderDetails.autoMountPoint();
    478487
    479488        /* Add new folder item: */
     
    502511    dlgFolderDetails.setName(pItem->m_strName);
    503512    dlgFolderDetails.setPermanent(pItem->m_enmType == MachineType);
     513    dlgFolderDetails.setWriteable(pItem->m_fWritable);
    504514    dlgFolderDetails.setAutoMount(pItem->m_fAutoMount);
    505     dlgFolderDetails.setWriteable(pItem->m_fWritable);
     515    dlgFolderDetails.setAutoMountPoint(pItem->m_strAutoMountPoint);
    506516
    507517    /* Run folder details dialog: */
     
    518528        pItem->m_strName = strName;
    519529        pItem->m_strPath = strPath;
     530        pItem->m_fWritable = dlgFolderDetails.isWriteable();
    520531        pItem->m_fAutoMount = dlgFolderDetails.isAutoMounted();
    521         pItem->m_fWritable = dlgFolderDetails.isWriteable();
     532        pItem->m_strAutoMountPoint = dlgFolderDetails.autoMountPoint();
    522533        pItem->updateFields();
    523534
     
    598609     *
    599610     * Columns
    600      * 0 = Tree view
    601      * 1 = Shared Folder name
    602      * 2 = Auto-mount flag
    603      * 3 = Writable flag
     611     * 0 = Tree view / name
     612     * 1 = Path
     613     * 2 = Writable flag
     614     * 3 = Auto-mount flag
     615     * 4 = Auto mount point
    604616     */
    605617    QAbstractItemView *pItemView = mTwFolders;
     
    610622    const int mw2 = qMax(pItemView->sizeHintForColumn(2), pItemHeader->sectionSizeHint(2));
    611623    const int mw3 = qMax(pItemView->sizeHintForColumn(3), pItemHeader->sectionSizeHint(3));
    612 
    613     const int w0 = mw0 < iTotal / 4 ? mw0 : iTotal / 4;
    614     const int w2 = mw2 < iTotal / 4 ? mw2 : iTotal / 4;
    615     const int w3 = mw3 < iTotal / 4 ? mw3 : iTotal / 4;
     624    const int mw4 = qMax(pItemView->sizeHintForColumn(4), pItemHeader->sectionSizeHint(4));
     625#if 0 /** @todo Neither approach is perfect.  Short folder names, short paths, plenty of white space, but there is often '...' in column 0. */
     626
     627    const int w0 = mw0 < iTotal / 5 ? mw0 : iTotal / 5;
     628    const int w2 = mw2 < iTotal / 5 ? mw2 : iTotal / 5;
     629    const int w3 = mw3 < iTotal / 5 ? mw3 : iTotal / 5;
     630    const int w4 = mw4 < iTotal / 5 ? mw4 : iTotal / 5;
    616631
    617632    /* Giving 1st column all the available space. */
     633    const int w1 = iTotal - w0 - w2 - w3 - w4;
     634#else
     635    const int mw1 = qMax(pItemView->sizeHintForColumn(1), pItemHeader->sectionSizeHint(1));
     636    const int iHintTotal = mw0 + mw1 + mw2 + mw3 + mw4;
     637    int w0, w1, w2, w3, w4;
     638    int cExcess = iTotal - iHintTotal;
     639    if (cExcess >= 0)
     640    {
     641        /* give excess width to column 1 (path) */
     642        w0 = mw0;
     643        w1 = mw1 + cExcess;
     644        w2 = mw2;
     645        w3 = mw3;
     646        w4 = mw4;
     647    }
     648    else
     649    {
     650        w0 = mw0 < iTotal / 5 ? mw0 : iTotal / 5;
     651        w2 = mw2 < iTotal / 5 ? mw2 : iTotal / 5;
     652        w3 = mw3 < iTotal / 5 ? mw3 : iTotal / 5;
     653        w4 = mw4 < iTotal / 5 ? mw4 : iTotal / 5;
     654        w1 = iTotal - w0 - w2 - w3 - w4;
     655    }
     656#endif
    618657    mTwFolders->setColumnWidth(0, w0);
    619     mTwFolders->setColumnWidth(1, iTotal - w0 - w2 - w3);
     658    mTwFolders->setColumnWidth(1, w1);
    620659    mTwFolders->setColumnWidth(2, w2);
    621660    mTwFolders->setColumnWidth(3, w3);
     661    mTwFolders->setColumnWidth(4, w4);
    622662}
    623663
     
    829869        pItem->m_strName = sharedFolderData.m_strName;
    830870        pItem->m_strPath = sharedFolderData.m_strPath;
     871        pItem->m_fWritable = sharedFolderData.m_fWritable;
    831872        pItem->m_fAutoMount = sharedFolderData.m_fAutoMount;
    832         pItem->m_fWritable = sharedFolderData.m_fWritable;
     873        pItem->m_strAutoMountPoint = sharedFolderData.m_strAutoMountPoint;
    833874        pItem->updateFields();
    834875
     
    10191060bool UIMachineSettingsSF::createSharedFolder(const UISettingsCacheSharedFolder &folderCache)
    10201061{
    1021     /* Prepare result: */
    1022     bool fSuccess = true;
    1023     /* Create folder: */
     1062    /* Get folder data: */
     1063    const UIDataSettingsSharedFolder &newFolderData = folderCache.data();
     1064    const UISharedFolderType enmFoldersType = newFolderData.m_enmType;
     1065    const QString strFolderName = newFolderData.m_strName;
     1066    const QString strFolderPath = newFolderData.m_strPath;
     1067    const bool fIsWritable = newFolderData.m_fWritable;
     1068    const bool fIsAutoMount = newFolderData.m_fAutoMount;
     1069    const QString strAutoMountPoint = newFolderData.m_strAutoMountPoint;
     1070
     1071    /* Get current folders: */
     1072    CSharedFolderVector folders;
     1073    bool fSuccess = getSharedFolders(enmFoldersType, folders);
     1074
     1075    /* Search for a folder with the same name: */
     1076    CSharedFolder comFolder;
    10241077    if (fSuccess)
    1025     {
    1026         /* Get folder data: */
    1027         const UIDataSettingsSharedFolder &newFolderData = folderCache.data();
    1028         const UISharedFolderType enmFoldersType = newFolderData.m_enmType;
    1029         const QString strFolderName = newFolderData.m_strName;
    1030         const QString strFolderPath = newFolderData.m_strPath;
    1031         const bool fIsAutoMount = newFolderData.m_fAutoMount;
    1032         const bool fIsWritable = newFolderData.m_fWritable;
    1033 
    1034         /* Get current folders: */
    1035         CSharedFolderVector folders;
    1036         if (fSuccess)
    1037             fSuccess = getSharedFolders(enmFoldersType, folders);
    1038 
    1039         /* Search for a folder with the same name: */
    1040         CSharedFolder comFolder;
    1041         if (fSuccess)
    1042             fSuccess = getSharedFolder(strFolderName, folders, comFolder);
    1043 
    1044         /* Make sure such folder doesn't exist: */
    1045         if (fSuccess && comFolder.isNull())
    1046         {
    1047             /* Create new folder: */
    1048             switch (enmFoldersType)
     1078        fSuccess = getSharedFolder(strFolderName, folders, comFolder);
     1079
     1080    /* Make sure such folder doesn't exist: */
     1081    if (fSuccess && comFolder.isNull())
     1082    {
     1083        /* Create new folder: */
     1084        switch (enmFoldersType)
     1085        {
     1086            case MachineType:
    10491087            {
    1050                 case MachineType:
    1051                 {
    1052                     /* Create new folder: */
    1053                     m_machine.CreateSharedFolder(strFolderName, strFolderPath, fIsWritable, fIsAutoMount);
    1054                     /* Check that machine is OK: */
    1055                     fSuccess = m_machine.isOk();
    1056                     if (!fSuccess)
    1057                     {
    1058                         /* Show error message: */
    1059                         notifyOperationProgressError(UIErrorString::formatErrorInfo(m_machine));
    1060                     }
    1061                     break;
    1062                 }
    1063                 case ConsoleType:
    1064                 {
    1065                     /* Create new folder: */
    1066                     m_console.CreateSharedFolder(strFolderName, strFolderPath, fIsWritable, fIsAutoMount);
    1067                     /* Check that console is OK: */
    1068                     fSuccess = m_console.isOk();
    1069                     if (!fSuccess)
    1070                     {
    1071                         /* Show error message: */
    1072                         notifyOperationProgressError(UIErrorString::formatErrorInfo(m_console));
    1073                     }
    1074                     break;
    1075                 }
    1076                 default:
    1077                     break;
     1088                /* Create new folder: */
     1089                m_machine.CreateSharedFolder(strFolderName, strFolderPath, fIsWritable, fIsAutoMount, strAutoMountPoint);
     1090                /* Show error if the operation failed: */
     1091                fSuccess = m_machine.isOk();
     1092                if (!fSuccess)
     1093                    notifyOperationProgressError(UIErrorString::formatErrorInfo(m_machine));
     1094                break;
    10781095            }
    1079         }
    1080     }
     1096            case ConsoleType:
     1097            {
     1098                /* Create new folder: */
     1099                m_console.CreateSharedFolder(strFolderName, strFolderPath, fIsWritable, fIsAutoMount, strAutoMountPoint);
     1100                /* Show error if the operation failed: */
     1101                fSuccess = m_console.isOk();
     1102                if (!fSuccess)
     1103                    notifyOperationProgressError(UIErrorString::formatErrorInfo(m_console));
     1104                break;
     1105            }
     1106            default:
     1107                break;
     1108        }
     1109    }
     1110
    10811111    /* Return result: */
    10821112    return fSuccess;
  • trunk/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsSF.ui

    r67067 r75380  
    8787        <column>
    8888         <property name="text">
    89           <string>Auto-mount</string>
     89          <string>Access</string>
    9090         </property>
    9191        </column>
    9292        <column>
    9393         <property name="text">
    94           <string>Access</string>
     94          <string>Auto Mount</string>
     95         </property>
     96        </column>
     97        <column>
     98         <property name="text">
     99          <string>At</string>
    95100         </property>
    96101        </column>
  • trunk/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsSFDetails.cpp

    r69500 r75380  
    110110}
    111111
     112void UIMachineSettingsSFDetails::setAutoMountPoint(const QString &strAutoMountPoint)
     113{
     114    mLeAutoMountPoint->setText(strAutoMountPoint);
     115}
     116
     117QString UIMachineSettingsSFDetails::autoMountPoint() const
     118{
     119    return mLeAutoMountPoint->text();
     120}
     121
    112122void UIMachineSettingsSFDetails::setPermanent(bool fPermanent)
    113123{
  • trunk/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsSFDetails.h

    r72109 r75380  
    1616 */
    1717
    18 #ifndef __UIMachineSettingsSFDetails_h__
    19 #define __UIMachineSettingsSFDetails_h__
     18#ifndef ___UIMachineSettingsSFDetails_h___
     19#define ___UIMachineSettingsSFDetails_h___
    2020
    2121/* Includes */
     
    5656    bool isAutoMounted() const;
    5757
     58    void setAutoMountPoint(const QString &strAutoMountPoint);
     59    QString autoMountPoint() const;
     60
    5861    void setPermanent(bool fPermanent);
    5962    bool isPermanent() const;
     
    7578};
    7679
    77 #endif // __UIMachineSettingsSFDetails_h__
     80#endif // !___UIMachineSettingsSFDetails_h___
  • trunk/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsSFDetails.ui

    r67067 r75380  
    7474    </widget>
    7575   </item>
     76   <item row="4" column="0" >
     77    <widget class="QLabel" name="mLbAutoMountPoint" >
     78     <property name="text" >
     79      <string>Mount point:</string>
     80     </property>
     81     <property name="alignment" >
     82      <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
     83     </property>
     84    </widget>
     85   </item>
    7686   <item row="4" column="1" >
     87    <widget class="QLineEdit" name="mLeAutoMountPoint" >
     88     <property name="toolTip" >
     89      <string>Where to automatically mount the folder in the guest.  A drive letter (e.g. 'G:') for Windows and OS/2 guests, path for the others.  If left empty the guest will pick something fitting.</string>
     90     </property>
     91    </widget>
     92   </item>
     93   <item row="5" column="1" >
    7794    <widget class="QCheckBox" name="mCbPermanent" >
    7895     <property name="toolTip" >
     
    84101    </widget>
    85102   </item>
    86    <item row="5" column="1" >
     103   <item row="6" column="1" >
    87104    <spacer>
    88105     <property name="orientation" >
     
    97114    </spacer>
    98115   </item>
    99    <item row="6" column="0" colspan="2" >
     116   <item row="7" column="0" colspan="2" >
    100117    <widget class="QIDialogButtonBox" name="mButtonBox" >
    101118     <property name="standardButtons" >
  • trunk/src/VBox/HostServices/SharedFolders/mappings.cpp

    r69500 r75380  
    8787              pLoadedMapping->pMapName->String.ucs2, pLoadedMapping->pszFolderName));
    8888    return vbsfMappingsAdd(pLoadedMapping->pszFolderName, pLoadedMapping->pMapName,
    89                            pLoadedMapping->fWritable, pLoadedMapping->fAutoMount,
     89                           pLoadedMapping->fWritable, pLoadedMapping->fAutoMount, pLoadedMapping->pAutoMountPoint,
    9090                           pLoadedMapping->fSymlinksCreate, /* fMissing = */ true, /* fPlaceholder = */ true);
    9191}
     
    200200 * We are always executed from one specific HGCM thread. So thread safe.
    201201 */
    202 int vbsfMappingsAdd(const char *pszFolderName, PSHFLSTRING pMapName,
    203                     bool fWritable, bool fAutoMount, bool fSymlinksCreate, bool fMissing, bool fPlaceholder)
     202int vbsfMappingsAdd(const char *pszFolderName, PSHFLSTRING pMapName, bool fWritable,
     203                    bool fAutoMount, PSHFLSTRING pAutoMountPoint, bool fSymlinksCreate, bool fMissing, bool fPlaceholder)
    204204{
    205205    unsigned i;
     
    232232            AssertRCReturn(rc, rc);
    233233
    234             FolderMapping[i].pszFolderName = RTStrDup(szAbsFolderName);
    235             if (!FolderMapping[i].pszFolderName)
     234            FolderMapping[i].pszFolderName   = RTStrDup(szAbsFolderName);
     235            FolderMapping[i].pMapName        = ShflStringDup(pMapName);
     236            FolderMapping[i].pAutoMountPoint = ShflStringDup(pAutoMountPoint);
     237            if (   !FolderMapping[i].pszFolderName
     238                || !FolderMapping[i].pMapName
     239                || !FolderMapping[i].pAutoMountPoint)
    236240            {
     241                RTStrFree(FolderMapping[i].pszFolderName);
     242                RTMemFree(FolderMapping[i].pMapName);
     243                RTMemFree(FolderMapping[i].pAutoMountPoint);
    237244                return VERR_NO_MEMORY;
    238245            }
    239 
    240             FolderMapping[i].pMapName = (PSHFLSTRING)RTMemAlloc(ShflStringSizeOfBuffer(pMapName));
    241             if (!FolderMapping[i].pMapName)
    242             {
    243                 RTStrFree(FolderMapping[i].pszFolderName);
    244                 AssertFailed();
    245                 return VERR_NO_MEMORY;
    246             }
    247 
    248             FolderMapping[i].pMapName->u16Length = pMapName->u16Length;
    249             FolderMapping[i].pMapName->u16Size   = pMapName->u16Size;
    250             memcpy(FolderMapping[i].pMapName->String.ucs2, pMapName->String.ucs2, pMapName->u16Size);
    251246
    252247            FolderMapping[i].fValid          = true;
  • trunk/src/VBox/HostServices/SharedFolders/mappings.h

    r69500 r75380  
     1/* $Id$ */
    12/** @file
    2  * Shared folders: Mappings header.
     3 * Shared folders service - Mappings header.
    34 */
    45
     
    2324typedef struct
    2425{
    25     char        *pszFolderName;       /**< directory at the host to share with the guest */
    26     PSHFLSTRING pMapName;             /**< share name for the guest */
    27     uint32_t    cMappings;            /**< number of mappings */
    28     bool        fValid;               /**< mapping entry is used/valid */
    29     bool        fHostCaseSensitive;   /**< host file name space is case-sensitive */
    30     bool        fGuestCaseSensitive;  /**< guest file name space is case-sensitive */
    31     bool        fWritable;            /**< folder is writable for the guest */
    32     bool        fAutoMount;           /**< folder will be auto-mounted by the guest */
    33     bool        fSymlinksCreate;      /**< guest is able to create symlinks */
    34     bool        fMissing;             /**< mapping not invalid but host path does not exist.
    35                                            Any guest operation on such a folder fails! */
    36     bool        fPlaceholder;         /**< mapping does not exist in the VM settings but the guest
    37                                            still has. fMissing is always true for this mapping. */
     26    char       *pszFolderName;          /**< Directory at the host to share with the guest. */
     27    PSHFLSTRING pMapName;               /**< Share name for the guest. */
     28    uint32_t    cMappings;              /**< Number of mappings. */
     29    bool        fValid;                 /**< Mapping entry is used/valid. */
     30    bool        fHostCaseSensitive;     /**< Host file name space is case-sensitive. */
     31    bool        fGuestCaseSensitive;    /**< Guest file name space is case-sensitive. */
     32    bool        fWritable;              /**< Folder is writable for the guest. */
     33    PSHFLSTRING pAutoMountPoint;        /**< Where the guest should try auto-mount the folder. */
     34    bool        fAutoMount;             /**< Folder will be auto-mounted by the guest. */
     35    bool        fSymlinksCreate;        /**< Guest is able to create symlinks. */
     36    bool        fMissing;               /**< Mapping not invalid but host path does not exist.
     37                                             Any guest operation on such a folder fails! */
     38    bool        fPlaceholder;           /**< Mapping does not exist in the VM settings but the guest
     39                                             still has. fMissing is always true for this mapping. */
    3840} MAPPING;
    3941/** Pointer to a MAPPING structure. */
     
    4446bool vbsfMappingQuery(uint32_t iMapping, PMAPPING *pMapping);
    4547
    46 int vbsfMappingsAdd(const char *pszFolderName, PSHFLSTRING pMapName,
    47                     bool fWritable, bool fAutoMount, bool fCreateSymlinks, bool fMissing, bool fPlaceholder);
     48int vbsfMappingsAdd(const char *pszFolderName, PSHFLSTRING pMapName, bool fWritable,
     49                    bool fAutoMount, PSHFLSTRING pAutoMountPoint, bool fCreateSymlinks, bool fMissing, bool fPlaceholder);
    4850int vbsfMappingsRemove(PSHFLSTRING pMapName);
    4951
  • trunk/src/VBox/HostServices/SharedFolders/service.cpp

    r69500 r75380  
    2929#include <VBox/vmm/pdmifs.h>
    3030
    31 #define SHFL_SSM_VERSION_FOLDERNAME_UTF16   2
    32 #define SHFL_SSM_VERSION                    3
     31#define SHFL_SAVED_STATE_VERSION_FOLDERNAME_UTF16       2
     32#define SHFL_SAVED_STATE_VERSION_PRE_AUTO_MOUNT_POINT   3
     33#define SHFL_SAVED_STATE_VERSION                        4
    3334
    3435
     
    120121    Log(("SharedFolders host service: saving state, u32ClientID = %u\n", u32ClientID));
    121122
    122     int rc = SSMR3PutU32(pSSM, SHFL_SSM_VERSION);
     123    int rc = SSMR3PutU32(pSSM, SHFL_SAVED_STATE_VERSION);
    123124    AssertRCReturn(rc, rc);
    124125
     
    147148        if (pFolderMapping && pFolderMapping->fValid)
    148149        {
    149             uint32_t len;
    150 
    151             len = (uint32_t)strlen(pFolderMapping->pszFolderName);
    152             rc = SSMR3PutU32(pSSM, len);
    153             AssertRCReturn(rc, rc);
    154 
    155             rc = SSMR3PutStrZ(pSSM, pFolderMapping->pszFolderName);
    156             AssertRCReturn(rc, rc);
     150            uint32_t len = (uint32_t)strlen(pFolderMapping->pszFolderName);
     151            SSMR3PutU32(pSSM, len);
     152            SSMR3PutStrZ(pSSM, pFolderMapping->pszFolderName);
    157153
    158154            len = ShflStringSizeOfBuffer(pFolderMapping->pMapName);
    159             rc = SSMR3PutU32(pSSM, len);
    160             AssertRCReturn(rc, rc);
    161 
    162             rc = SSMR3PutMem(pSSM, pFolderMapping->pMapName, len);
    163             AssertRCReturn(rc, rc);
    164 
    165             rc = SSMR3PutBool(pSSM, pFolderMapping->fHostCaseSensitive);
    166             AssertRCReturn(rc, rc);
    167 
    168             rc = SSMR3PutBool(pSSM, pFolderMapping->fGuestCaseSensitive);
     155            SSMR3PutU32(pSSM, len);
     156            SSMR3PutMem(pSSM, pFolderMapping->pMapName, len);
     157
     158            SSMR3PutBool(pSSM, pFolderMapping->fHostCaseSensitive);
     159
     160            SSMR3PutBool(pSSM, pFolderMapping->fGuestCaseSensitive);
     161
     162            len = ShflStringSizeOfBuffer(pFolderMapping->pAutoMountPoint);
     163            SSMR3PutU32(pSSM, len);
     164            rc = SSMR3PutMem(pSSM, pFolderMapping->pAutoMountPoint, len);
    169165            AssertRCReturn(rc, rc);
    170166        }
     
    190186    AssertRCReturn(rc, rc);
    191187
    192     if (   version > SHFL_SSM_VERSION
    193         || version < SHFL_SSM_VERSION_FOLDERNAME_UTF16)
     188    if (   version > SHFL_SAVED_STATE_VERSION
     189        || version < SHFL_SAVED_STATE_VERSION_FOLDERNAME_UTF16)
    194190        return VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION;
    195191
     
    214210        /* Load the saved mapping description and try to find it in the mappings. */
    215211        MAPPING mapping;
    216         memset (&mapping, 0, sizeof (mapping));
     212        RT_ZERO(mapping);
    217213
    218214        /* restore the folder mapping counter. */
     
    225221        if (mapping.fValid)
    226222        {
    227             uint32_t cbFolderName;
     223            uint32_t cb;
     224
     225            /* Load the host path name. */
     226            rc = SSMR3GetU32(pSSM, &cb);
     227            AssertRCReturn(rc, rc);
     228
    228229            char *pszFolderName;
    229 
    230             uint32_t cbMapName;
    231             PSHFLSTRING pMapName;
    232 
    233             /* Load the host path name. */
    234             rc = SSMR3GetU32(pSSM, &cbFolderName);
    235             AssertRCReturn(rc, rc);
    236 
    237             if (version == SHFL_SSM_VERSION_FOLDERNAME_UTF16)
    238             {
    239                 PSHFLSTRING pFolderName = (PSHFLSTRING)RTMemAlloc(cbFolderName);
     230            if (version == SHFL_SAVED_STATE_VERSION_FOLDERNAME_UTF16)
     231            {
     232                AssertReturn(cb > SHFLSTRING_HEADER_SIZE && cb <= UINT16_MAX + SHFLSTRING_HEADER_SIZE && !(cb & 1),
     233                             SSMR3SetLoadError(pSSM, VERR_SSM_DATA_UNIT_FORMAT_CHANGED, RT_SRC_POS, "Bad folder name size: %#x\n", cb));
     234                PSHFLSTRING pFolderName = (PSHFLSTRING)RTMemAlloc(cb);
    240235                AssertReturn(pFolderName != NULL, VERR_NO_MEMORY);
    241236
    242                 rc = SSMR3GetMem(pSSM, pFolderName, cbFolderName);
     237                rc = SSMR3GetMem(pSSM, pFolderName, cb);
    243238                AssertRCReturn(rc, rc);
     239                AssertReturn(pFolderName->u16Length < cb && pFolderName->u16Size < pFolderName->u16Length,
     240                             SSMR3SetLoadError(pSSM, VERR_SSM_DATA_UNIT_FORMAT_CHANGED, RT_SRC_POS,
     241                                               "Bad folder name string: %#x/%#x cb=%#x\n",
     242                                               pFolderName->u16Size, pFolderName->u16Length, cb));
    244243
    245244                rc = RTUtf16ToUtf8(pFolderName->String.ucs2, &pszFolderName);
     
    249248            else
    250249            {
    251                 pszFolderName = (char*)RTStrAlloc(cbFolderName + 1);
     250                pszFolderName = (char *)RTStrAlloc(cb + 1);
    252251                AssertReturn(pszFolderName, VERR_NO_MEMORY);
    253252
    254                 rc = SSMR3GetStrZ(pSSM, pszFolderName, cbFolderName + 1);
     253                rc = SSMR3GetStrZ(pSSM, pszFolderName, cb + 1);
    255254                AssertRCReturn(rc, rc);
    256255                mapping.pszFolderName = pszFolderName;
     
    258257
    259258            /* Load the map name. */
    260             rc = SSMR3GetU32(pSSM, &cbMapName);
     259            rc = SSMR3GetU32(pSSM, &cb);
    261260            AssertRCReturn(rc, rc);
    262 
    263             pMapName = (PSHFLSTRING)RTMemAlloc(cbMapName);
     261            AssertReturn(cb > SHFLSTRING_HEADER_SIZE && cb <= UINT16_MAX + SHFLSTRING_HEADER_SIZE && !(cb & 1),
     262                         SSMR3SetLoadError(pSSM, VERR_SSM_DATA_UNIT_FORMAT_CHANGED, RT_SRC_POS, "Bad map name size: %#x\n", cb));
     263
     264            PSHFLSTRING pMapName = (PSHFLSTRING)RTMemAlloc(cb);
    264265            AssertReturn(pMapName != NULL, VERR_NO_MEMORY);
    265266
    266             rc = SSMR3GetMem(pSSM, pMapName, cbMapName);
     267            rc = SSMR3GetMem(pSSM, pMapName, cb);
    267268            AssertRCReturn(rc, rc);
    268 
     269            AssertReturn(pMapName->u16Length < cb && pMapName->u16Size < pMapName->u16Length,
     270                         SSMR3SetLoadError(pSSM, VERR_SSM_DATA_UNIT_FORMAT_CHANGED, RT_SRC_POS,
     271                                           "Bad map name string: %#x/%#x cb=%#x\n",
     272                                           pMapName->u16Size, pMapName->u16Length, cb));
     273
     274            /* Load case sensitivity config. */
    269275            rc = SSMR3GetBool(pSSM, &mapping.fHostCaseSensitive);
    270276            AssertRCReturn(rc, rc);
     
    273279            AssertRCReturn(rc, rc);
    274280
     281            /* Load the auto mount point. */
     282            PSHFLSTRING pAutoMountPoint;
     283            if (version > SHFL_SAVED_STATE_VERSION_PRE_AUTO_MOUNT_POINT)
     284            {
     285                rc = SSMR3GetU32(pSSM, &cb);
     286                AssertRCReturn(rc, rc);
     287                AssertReturn(cb > SHFLSTRING_HEADER_SIZE && cb <= UINT16_MAX + SHFLSTRING_HEADER_SIZE && !(cb & 1),
     288                             SSMR3SetLoadError(pSSM, VERR_SSM_DATA_UNIT_FORMAT_CHANGED, RT_SRC_POS, "Bad auto mount point size: %#x\n", cb));
     289
     290                pAutoMountPoint = (PSHFLSTRING)RTMemAlloc(cb);
     291                AssertReturn(pAutoMountPoint != NULL, VERR_NO_MEMORY);
     292
     293                rc = SSMR3GetMem(pSSM, pAutoMountPoint, cb);
     294                AssertRCReturn(rc, rc);
     295                AssertReturn(pAutoMountPoint->u16Length < cb && pAutoMountPoint->u16Size < pAutoMountPoint->u16Length,
     296                             SSMR3SetLoadError(pSSM, VERR_SSM_DATA_UNIT_FORMAT_CHANGED, RT_SRC_POS,
     297                                               "Bad auto mount point string: %#x/%#x cb=%#x\n",
     298                                               pAutoMountPoint->u16Size, pAutoMountPoint->u16Length, cb));
     299
     300            }
     301            else
     302            {
     303                pAutoMountPoint = ShflStringDupUtf8("");
     304                AssertReturn(pAutoMountPoint, VERR_NO_MEMORY);
     305            }
     306
    275307            mapping.pszFolderName = pszFolderName;
    276308            mapping.pMapName = pMapName;
     309            mapping.pAutoMountPoint = pAutoMountPoint;
    277310
    278311            /* 'i' is the root handle of the saved mapping. */
     
    284317            }
    285318
     319            RTMemFree(pAutoMountPoint);
    286320            RTMemFree(pMapName);
    287321            RTStrFree(pszFolderName);
     
    13151349            rc = VERR_INVALID_PARAMETER;
    13161350        }
    1317         else if (   paParms[0].type != VBOX_HGCM_SVC_PARM_PTR     /* host folder name */
    1318                  || paParms[1].type != VBOX_HGCM_SVC_PARM_PTR     /* guest map name */
     1351        else if (   paParms[0].type != VBOX_HGCM_SVC_PARM_PTR     /* host folder path */
     1352                 || paParms[1].type != VBOX_HGCM_SVC_PARM_PTR     /* map name */
    13191353                 || paParms[2].type != VBOX_HGCM_SVC_PARM_32BIT   /* fFlags */
     1354                 || paParms[3].type != VBOX_HGCM_SVC_PARM_PTR     /* auto mount point */
    13201355                )
    13211356        {
     
    13251360        {
    13261361            /* Fetch parameters. */
    1327             SHFLSTRING *pFolderName = (SHFLSTRING *)paParms[0].u.pointer.addr;
    1328             SHFLSTRING *pMapName    = (SHFLSTRING *)paParms[1].u.pointer.addr;
    1329             uint32_t fFlags         = paParms[2].u.uint32;
     1362            SHFLSTRING *pHostPath       = (SHFLSTRING *)paParms[0].u.pointer.addr;
     1363            SHFLSTRING *pMapName        = (SHFLSTRING *)paParms[1].u.pointer.addr;
     1364            uint32_t fFlags             = paParms[2].u.uint32;
     1365            SHFLSTRING *pAutoMountPoint = (SHFLSTRING *)paParms[3].u.pointer.addr;
    13301366
    13311367            /* Verify parameters values. */
    1332             if (    !ShflStringIsValidIn(pFolderName, paParms[0].u.pointer.size, false /*fUtf8Not16*/)
     1368            if (    !ShflStringIsValidIn(pHostPath, paParms[0].u.pointer.size, false /*fUtf8Not16*/)
    13331369                ||  !ShflStringIsValidIn(pMapName, paParms[1].u.pointer.size, false /*fUtf8Not16*/)
     1370                ||  !ShflStringIsValidIn(pAutoMountPoint, paParms[3].u.pointer.size, false /*fUtf8Not16*/)
    13341371               )
    13351372            {
     
    13381375            else
    13391376            {
    1340                 LogRel(("    Host path '%ls', map name '%ls', %s, automount=%s, create_symlinks=%s, missing=%s\n",
    1341                         ((SHFLSTRING *)paParms[0].u.pointer.addr)->String.ucs2,
    1342                         ((SHFLSTRING *)paParms[1].u.pointer.addr)->String.ucs2,
     1377                LogRel(("    Host path '%ls', map name '%ls', %s, automount=%s, automntpnt=%s, create_symlinks=%s, missing=%s\n",
     1378                        pHostPath->String.utf16, pMapName->String.utf16,
    13431379                        RT_BOOL(fFlags & SHFL_ADD_MAPPING_F_WRITABLE) ? "writable" : "read-only",
    13441380                        RT_BOOL(fFlags & SHFL_ADD_MAPPING_F_AUTOMOUNT) ? "true" : "false",
     1381                        pAutoMountPoint->String.utf16,
    13451382                        RT_BOOL(fFlags & SHFL_ADD_MAPPING_F_CREATE_SYMLINKS) ? "true" : "false",
    13461383                        RT_BOOL(fFlags & SHFL_ADD_MAPPING_F_MISSING) ? "true" : "false"));
    13471384
    1348                 char *pszFolderName;
    1349                 rc = RTUtf16ToUtf8(pFolderName->String.ucs2, &pszFolderName);
    1350 
     1385                char *pszHostPath;
     1386                rc = RTUtf16ToUtf8(pHostPath->String.ucs2, &pszHostPath);
    13511387                if (RT_SUCCESS(rc))
    13521388                {
    13531389                    /* Execute the function. */
    1354                     rc = vbsfMappingsAdd(pszFolderName, pMapName,
     1390                    rc = vbsfMappingsAdd(pszHostPath, pMapName,
    13551391                                         RT_BOOL(fFlags & SHFL_ADD_MAPPING_F_WRITABLE),
    13561392                                         RT_BOOL(fFlags & SHFL_ADD_MAPPING_F_AUTOMOUNT),
     1393                                         pAutoMountPoint,
    13571394                                         RT_BOOL(fFlags & SHFL_ADD_MAPPING_F_CREATE_SYMLINKS),
    13581395                                         RT_BOOL(fFlags & SHFL_ADD_MAPPING_F_MISSING),
     
    13631400                        ; /* none */
    13641401                    }
    1365                     RTStrFree(pszFolderName);
     1402                    RTStrFree(pszHostPath);
    13661403                }
    13671404            }
  • trunk/src/VBox/HostServices/SharedFolders/testcase/tstSharedFolderService.cpp

    r69753 r75380  
    617617    union TESTSHFLSTRING FolderName;
    618618    union TESTSHFLSTRING Mapping;
     619    union TESTSHFLSTRING AutoMountPoint;
    619620    VBOXHGCMCALLHANDLE_TYPEDEF callHandle = { VINF_SUCCESS };
    620621    int rc;
     
    627628    fillTestShflString(&FolderName, pcszFolderName);
    628629    fillTestShflString(&Mapping, pcszMapping);
     630    fillTestShflString(&AutoMountPoint, "");
    629631    aParms[0].setPointer(&FolderName,   RT_UOFFSETOF(SHFLSTRING, String)
    630632                                      + FolderName.string.u16Size);
     
    632634                                   + Mapping.string.u16Size);
    633635    aParms[2].setUInt32(1);
     636    aParms[3].setPointer(&AutoMountPoint, SHFLSTRING_HEADER_SIZE + AutoMountPoint.string.u16Size);
    634637    rc = psvcTable->pfnHostCall(psvcTable->pvService, SHFL_FN_ADD_MAPPING,
    635638                                SHFL_CPARMS_ADD_MAPPING, aParms);
  • trunk/src/VBox/Main/idl/VirtualBox.xidl

    r75371 r75380  
    19601960  <interface
    19611961    name="IVirtualBox" extends="$unknown"
    1962     uuid="176b85cd-4bc2-453e-9228-f408c5282267"
     1962    uuid="606da9e2-032b-4c82-3bf0-3675789df7b9"
    19631963    wsmap="managed"
    19641964    reservedMethods="7" reservedAttributes="12"
     
    26922692        <desc>Whether the share gets automatically mounted by the guest
    26932693          or not.</desc>
     2694      </param>
     2695      <param name="autoMountPoint" type="wstring" dir="in">
     2696        <desc>Where the guest should automatically mount the folder, if possible.
     2697          For Windows and OS/2 guests this should be a drive letter, while other
     2698          guests it should be a absolute directory.
     2699        </desc>
    26942700      </param>
    26952701    </method>
     
    52215227  <interface
    52225228    name="IMachine" extends="$unknown"
    5223     uuid="BD65ADC6-7F47-4F69-B881-96EA06CF9924"
     5229    uuid="cfc5671a-2309-4893-8744-ba4c07d65d86"
    52245230    wsmap="managed"
    52255231    wrap-hint-server-addinterfaces="IInternalMachineControl"
     
    78057811          or not.</desc>
    78067812      </param>
     7813      <param name="autoMountPoint" type="wstring" dir="in">
     7814        <desc>Where the guest should automatically mount the folder, if possible.
     7815          For Windows and OS/2 guests this should be a drive letter, while other
     7816          guests it should be a absolute directory.
     7817        </desc>
     7818      </param>
    78077819    </method>
    78087820
     
    93179329        <desc>Whether the share gets automatically mounted by the guest
    93189330          or not.</desc>
     9331      </param>
     9332      <param name="autoMountPoint" type="wstring" dir="in">
     9333        <desc>Where the guest should automatically mount the folder, if possible.
     9334          For Windows and OS/2 guests this should be a drive letter, while other
     9335          guests it should be a absolute directory.
     9336        </desc>
    93199337      </param>
    93209338    </method>
     
    2052020538  <interface
    2052120539    name="ISharedFolder" extends="$unknown"
    20522     uuid="15aabe95-e594-4e18-9222-b5e83a23f1da"
     20540    uuid="e02c0f1e-15f4-440e-3814-bbf613f8448b"
    2052320541    wsmap="struct"
    2052420542    reservedAttributes="4"
     
    2060220620      <desc>
    2060320621        Whether the folder gets automatically mounted by the guest or not.
     20622      </desc>
     20623    </attribute>
     20624
     20625    <attribute name="autoMountPoint" type="wstring" readonly="yes">
     20626      <desc>
     20627        Desired mount point in the guest for automatically mounting the folder
     20628        when <link to="ISharedFolder::autoMount"/> is set.  For Windows and
     20629        OS/2 guests this should be a drive letter, while other guests it should
     20630        be a absolute directory.
     20631
     20632        When empty the guest will choose a mount point.  The guest may do so
     20633        too should the specified mount point be in use or otherwise unusable.
    2060420634      </desc>
    2060520635    </attribute>
  • trunk/src/VBox/Main/include/ConsoleImpl.h

    r75361 r75380  
    342342                               const com::Utf8Str &aHostPath,
    343343                               BOOL aWritable,
    344                                BOOL aAutomount);
     344                               BOOL aAutomount,
     345                               const com::Utf8Str &aAutoMountPoint);
    345346    HRESULT removeSharedFolder(const com::Utf8Str &aName);
    346347    HRESULT teleport(const com::Utf8Str &aHostname,
     
    549550        SharedFolderData(const Utf8Str &aHostPath,
    550551                         bool aWritable,
    551                          bool aAutoMount)
    552            : m_strHostPath(aHostPath),
    553              m_fWritable(aWritable),
    554              m_fAutoMount(aAutoMount)
     552                         bool aAutoMount,
     553                         const Utf8Str &aAutoMountPoint)
     554            : m_strHostPath(aHostPath)
     555            , m_fWritable(aWritable)
     556            , m_fAutoMount(aAutoMount)
     557            , m_strAutoMountPoint(aAutoMountPoint)
    555558        { }
    556559
    557560        // copy constructor
    558561        SharedFolderData(const SharedFolderData& aThat)
    559            : m_strHostPath(aThat.m_strHostPath),
    560              m_fWritable(aThat.m_fWritable),
    561              m_fAutoMount(aThat.m_fAutoMount)
     562            : m_strHostPath(aThat.m_strHostPath)
     563            , m_fWritable(aThat.m_fWritable)
     564            , m_fAutoMount(aThat.m_fAutoMount)
     565            , m_strAutoMountPoint(aThat.m_strAutoMountPoint)
    562566        { }
    563567
     
    565569        bool m_fWritable;
    566570        bool m_fAutoMount;
     571        Utf8Str m_strAutoMountPoint;
    567572    };
    568573
     
    820825
    821826    static const char *sSSMConsoleUnit;
    822     static uint32_t sSSMConsoleVer;
    823827
    824828    HRESULT i_loadDataFromSavedState();
  • trunk/src/VBox/Main/include/MachineImpl.h

    r75361 r75380  
    11151115                               const com::Utf8Str &aHostPath,
    11161116                               BOOL aWritable,
    1117                                BOOL aAutomount);
     1117                               BOOL aAutomount,
     1118                               const com::Utf8Str &aAutoMountPoint);
    11181119    HRESULT removeSharedFolder(const com::Utf8Str &aName);
    11191120    HRESULT canShowConsoleWindow(BOOL *aCanShow);
  • trunk/src/VBox/Main/include/SharedFolderImpl.h

    r69500 r75380  
    11/* $Id$ */
    22/** @file
    3  *
    43 * VirtualBox COM class implementation
    54 */
     
    3635
    3736    // public initializer/uninitializer for internal purposes only
    38     HRESULT init(Machine *aMachine, const com::Utf8Str &aName, const com::Utf8Str &aHostPath, bool aWritable, bool aAutoMount, bool fFailOnError);
     37    HRESULT init(Machine *aMachine, const com::Utf8Str &aName, const com::Utf8Str &aHostPath,
     38                 bool aWritable, bool aAutoMount, const com::Utf8Str &aAutoMountPoint, bool fFailOnError);
    3939    HRESULT initCopy(Machine *aMachine, SharedFolder *aThat);
    40     HRESULT init(Console *aConsole, const com::Utf8Str &aName, const com::Utf8Str &aHostPath, bool aWritable, bool aAutoMount, bool fFailOnError);
    41 //     HRESULT init(VirtualBox *aVirtualBox, const Utf8Str &aName, const Utf8Str &aHostPath, bool aWritable, bool aAutoMount, bool fFailOnError);
     40    HRESULT init(Console *aConsole, const com::Utf8Str &aName, const com::Utf8Str &aHostPath,
     41                 bool aWritable, bool aAutoMount, const com::Utf8Str &aAutoMountPoint, bool fFailOnError);
     42//     HRESULT init(VirtualBox *aVirtualBox, const Utf8Str &aName, const Utf8Str &aHostPath,
     43//                  bool aWritable, const com::Utf8Str &aAutoMountPoint, bool aAutoMount, bool fFailOnError);
    4244    void uninit();
    4345
     
    4951     * @return
    5052     */
    51     const Utf8Str& i_getName() const;
     53    const Utf8Str &i_getName() const;
    5254
    5355    /**
     
    5557     * @return
    5658     */
    57     const Utf8Str& i_getHostPath() const;
     59    const Utf8Str &i_getHostPath() const;
    5860
    5961    /**
     
    6971    bool i_isAutoMounted() const;
    7072
     73    /**
     74     * Public internal method for getting the auto mount point.
     75     */
     76    const Utf8Str &i_getAutoMountPoint() const;
     77
    7178protected:
    7279
     
    7683                            bool aWritable,
    7784                            bool aAutoMount,
     85                            const com::Utf8Str &aAutoMountPoint,
    7886                            bool fFailOnError);
    7987private:
     
    8593    HRESULT getWritable(BOOL *aWritable);
    8694    HRESULT getAutoMount(BOOL *aAutoMount);
     95    HRESULT getAutoMountPoint(com::Utf8Str &aAutoMountPoint);
    8796    HRESULT getLastAccessError(com::Utf8Str &aLastAccessError);
    8897
     
    101110};
    102111
    103 #endif // ____H_SHAREDFOLDERIMPL
     112#endif // !____H_SHAREDFOLDERIMPL
    104113/* vi: set tabstop=4 shiftwidth=4 expandtab: */
  • trunk/src/VBox/Main/include/VirtualBoxImpl.h

    r73716 r75380  
    329329                               const com::Utf8Str &aHostPath,
    330330                               BOOL aWritable,
    331                                BOOL aAutomount);
     331                               BOOL aAutomount,
     332                               const com::Utf8Str &aAutoMountPoint);
    332333    HRESULT removeSharedFolder(const com::Utf8Str &aName);
    333334    HRESULT getExtraDataKeys(std::vector<com::Utf8Str> &aKeys);
  • trunk/src/VBox/Main/src-all/SharedFolderImpl.cpp

    r73003 r75380  
    4646    bool            fWritable;
    4747    bool            fAutoMount;
     48    const Utf8Str   strAutoMountPoint;
    4849    Utf8Str         strLastAccessError;
    4950};
     
    9596 *  @param aWritable    writable if true, readonly otherwise
    9697 *  @param aAutoMount   if auto mounted by guest true, false otherwise
     98 *  @param aAutoMountPoint Where the guest should try auto mount it.
    9799 *  @param fFailOnError Whether to fail with an error if the shared folder path is bad.
    98100 *
     
    104106                           bool aWritable,
    105107                           bool aAutoMount,
     108                           const Utf8Str &aAutoMountPoint,
    106109                           bool fFailOnError)
    107110{
     
    112115    unconst(mMachine) = aMachine;
    113116
    114     HRESULT rc = i_protectedInit(aMachine, aName, aHostPath, aWritable, aAutoMount, fFailOnError);
     117    HRESULT rc = i_protectedInit(aMachine, aName, aHostPath, aWritable, aAutoMount, aAutoMountPoint, fFailOnError);
    115118
    116119    /* Confirm a successful initialization when it's the case */
     
    146149                                 aThat->m->fWritable,
    147150                                 aThat->m->fAutoMount,
     151                                 aThat->m->strAutoMountPoint,
    148152                                 false /* fFailOnError */ );
    149153
     
    166170 *  @param aHostPath    full path to the shared folder on the host
    167171 *  @param aWritable    writable if true, readonly otherwise
     172 *  @param aAutoMountPoint Where the guest should try auto mount it.
    168173 *  @param fFailOnError Whether to fail with an error if the shared folder path is bad.
    169174 *
     
    175180                           bool aWritable,
    176181                           bool aAutoMount,
     182                           const Utf8Str &aAutoMountPoint
    177183                           bool fFailOnError)
    178184{
     
    183189    unconst(mVirtualBox) = aVirtualBox;
    184190
    185     HRESULT rc = protectedInit(aVirtualBox, aName, aHostPath, aWritable, aAutoMount);
     191    HRESULT rc = protectedInit(aVirtualBox, aName, aHostPath, aWritable, aAutoMount, aAutoMountPoint, fFailOnError);
    186192
    187193    /* Confirm a successful initialization when it's the case */
     
    205211 *  @param aHostPath    full path to the shared folder on the host
    206212 *  @param aWritable    writable if true, readonly otherwise
     213 *  @param aAutoMountPoint Where the guest should try auto mount it.
    207214 *  @param fFailOnError Whether to fail with an error if the shared folder path is bad.
    208215 *
     
    214221                           bool aWritable,
    215222                           bool aAutoMount,
     223                           const Utf8Str &aAutoMountPoint,
    216224                           bool fFailOnError)
    217225{
     
    222230    unconst(mConsole) = aConsole;
    223231
    224     HRESULT rc = i_protectedInit(aConsole, aName, aHostPath, aWritable, aAutoMount, fFailOnError);
     232    HRESULT rc = i_protectedInit(aConsole, aName, aHostPath, aWritable, aAutoMount, aAutoMountPoint, fFailOnError);
    225233
    226234    /* Confirm a successful initialization when it's the case */
     
    243251                                      bool aWritable,
    244252                                      bool aAutoMount,
     253                                      const Utf8Str &aAutoMountPoint,
    245254                                      bool fFailOnError)
    246255{
     
    260269     * accept both the slashified paths and not. */
    261270#if defined (RT_OS_OS2) || defined (RT_OS_WINDOWS)
    262     if (hostPathLen > 2 &&
    263         RTPATH_IS_SEP (hostPath.c_str()[hostPathLen - 1]) &&
    264         RTPATH_IS_VOLSEP (hostPath.c_str()[hostPathLen - 2]))
     271    if (   hostPathLen > 2
     272        && RTPATH_IS_SEP(hostPath.c_str()[hostPathLen - 1])
     273        && RTPATH_IS_VOLSEP(hostPath.c_str()[hostPathLen - 2]))
    265274        ;
    266275#else
     
    292301    m->fWritable = aWritable;
    293302    m->fAutoMount = aAutoMount;
     303    unconst(m->strAutoMountPoint) = aAutoMountPoint;
    294304
    295305    return S_OK;
     
    385395}
    386396
     397HRESULT SharedFolder::getAutoMountPoint(com::Utf8Str &aAutoMountPoint)
     398{
     399    /* strAutoMountPoint is constant during life time, no need to lock. */
     400    aAutoMountPoint = m->strAutoMountPoint;
     401    return S_OK;
     402}
     403
     404
    387405HRESULT SharedFolder::getLastAccessError(com::Utf8Str &aLastAccessError)
    388406{
     
    415433}
    416434
     435const Utf8Str &SharedFolder::i_getAutoMountPoint() const
     436{
     437    return m->strAutoMountPoint;
     438}
     439
    417440/* vi: set tabstop=4 shiftwidth=4 expandtab: */
  • trunk/src/VBox/Main/src-client/ConsoleImpl.cpp

    r75361 r75380  
    15161516//static
    15171517const char *Console::sSSMConsoleUnit = "ConsoleData";
    1518 //static
    1519 uint32_t Console::sSSMConsoleVer = 0x00010001;
     1518/** The saved state version.  */
     1519#define CONSOLE_SAVED_STATE_VERSION                         UINT32_C(0x00010002)
     1520/** The saved state version, pre shared folder autoMountPoint.  */
     1521#define CONSOLE_SAVED_STATE_VERSION_PRE_AUTO_MOUNT_POINT    UINT32_C(0x00010001)
    15201522
    15211523inline static const char *networkAdapterTypeToName(NetworkAdapterType_T adapterType)
     
    15691571        uint32_t version = 0;
    15701572        vrc = SSMR3Seek(ssm, sSSMConsoleUnit, 0 /* iInstance */, &version);
    1571         if (SSM_VERSION_MAJOR(version) == SSM_VERSION_MAJOR(sSSMConsoleVer))
     1573        if (SSM_VERSION_MAJOR(version) == SSM_VERSION_MAJOR(CONSOLE_SAVED_STATE_VERSION))
    15721574        {
    15731575            if (RT_SUCCESS(vrc))
     
    16141616    AutoReadLock alock(that COMMA_LOCKVAL_SRC_POS);
    16151617
    1616     int vrc = SSMR3PutU32(pSSM, (uint32_t)that->m_mapSharedFolders.size());
    1617     AssertRC(vrc);
     1618    SSMR3PutU32(pSSM, (uint32_t)that->m_mapSharedFolders.size());
    16181619
    16191620    for (SharedFolderMap::const_iterator it = that->m_mapSharedFolders.begin();
     
    16251626        AutoReadLock sfLock(pSF COMMA_LOCKVAL_SRC_POS);
    16261627
    1627         Utf8Str name = pSF->i_getName();
    1628         vrc = SSMR3PutU32(pSSM, (uint32_t)name.length() + 1 /* term. 0 */);
    1629         AssertRC(vrc);
    1630         vrc = SSMR3PutStrZ(pSSM, name.c_str());
    1631         AssertRC(vrc);
    1632 
    1633         Utf8Str hostPath = pSF->i_getHostPath();
    1634         vrc = SSMR3PutU32(pSSM, (uint32_t)hostPath.length() + 1 /* term. 0 */);
    1635         AssertRC(vrc);
    1636         vrc = SSMR3PutStrZ(pSSM, hostPath.c_str());
    1637         AssertRC(vrc);
    1638 
    1639         vrc = SSMR3PutBool(pSSM, !!pSF->i_isWritable());
    1640         AssertRC(vrc);
    1641 
    1642         vrc = SSMR3PutBool(pSSM, !!pSF->i_isAutoMounted());
    1643         AssertRC(vrc);
    1644     }
    1645 
    1646     return;
     1628        const Utf8Str &name = pSF->i_getName();
     1629        SSMR3PutU32(pSSM, (uint32_t)name.length() + 1 /* term. 0 */);
     1630        SSMR3PutStrZ(pSSM, name.c_str());
     1631
     1632        const Utf8Str &hostPath = pSF->i_getHostPath();
     1633        SSMR3PutU32(pSSM, (uint32_t)hostPath.length() + 1 /* term. 0 */);
     1634        SSMR3PutStrZ(pSSM, hostPath.c_str());
     1635
     1636        SSMR3PutBool(pSSM, !!pSF->i_isWritable());
     1637        SSMR3PutBool(pSSM, !!pSF->i_isAutoMounted());
     1638
     1639        const Utf8Str &rStrAutoMountPoint = pSF->i_getAutoMountPoint();
     1640        SSMR3PutU32(pSSM, (uint32_t)rStrAutoMountPoint.length() + 1 /* term. 0 */);
     1641        SSMR3PutStrZ(pSSM, rStrAutoMountPoint.c_str());
     1642    }
    16471643}
    16481644
     
    16651661    LogFlowFunc(("\n"));
    16661662
    1667     if (SSM_VERSION_MAJOR_CHANGED(uVersion, sSSMConsoleVer))
     1663    if (SSM_VERSION_MAJOR_CHANGED(uVersion, CONSOLE_SAVED_STATE_VERSION))
    16681664        return VERR_VERSION_MISMATCH;
    16691665    Assert(uPass == SSM_PASS_FINAL); NOREF(uPass);
     
    17061702        bool autoMount = false;
    17071703
    1708         uint32_t szBuf = 0;
     1704        uint32_t cbStr = 0;
    17091705        char *buf = NULL;
    17101706
    1711         vrc = SSMR3GetU32(pSSM, &szBuf);
     1707        vrc = SSMR3GetU32(pSSM, &cbStr);
    17121708        AssertRCReturn(vrc, vrc);
    1713         buf = new char[szBuf];
    1714         vrc = SSMR3GetStrZ(pSSM, buf, szBuf);
     1709        buf = new char[cbStr];
     1710        vrc = SSMR3GetStrZ(pSSM, buf, cbStr);
    17151711        AssertRC(vrc);
    17161712        strName = buf;
    17171713        delete[] buf;
    17181714
    1719         vrc = SSMR3GetU32(pSSM, &szBuf);
     1715        vrc = SSMR3GetU32(pSSM, &cbStr);
    17201716        AssertRCReturn(vrc, vrc);
    1721         buf = new char[szBuf];
    1722         vrc = SSMR3GetStrZ(pSSM, buf, szBuf);
     1717        buf = new char[cbStr];
     1718        vrc = SSMR3GetStrZ(pSSM, buf, cbStr);
    17231719        AssertRC(vrc);
    17241720        strHostPath = buf;
    17251721        delete[] buf;
    17261722
    1727         if (u32Version > 0x00010000)
     1723        if (u32Version >= CONSOLE_SAVED_STATE_VERSION_PRE_AUTO_MOUNT_POINT)
    17281724            SSMR3GetBool(pSSM, &writable);
    17291725
    1730         if (u32Version > 0x00010000) // ???
     1726        if (   u32Version >= CONSOLE_SAVED_STATE_VERSION_PRE_AUTO_MOUNT_POINT
     1727#ifndef VBOX_OSE /* This broke saved state when introduced in r63916 (4.0). */
     1728            && SSMR3HandleRevision(pSSM) >= 63916
     1729#endif
     1730           )
    17311731            SSMR3GetBool(pSSM, &autoMount);
     1732
     1733        Utf8Str strAutoMountPoint;
     1734        if (u32Version >= CONSOLE_SAVED_STATE_VERSION)
     1735        {
     1736            vrc = SSMR3GetU32(pSSM, &cbStr);
     1737            AssertRCReturn(vrc, vrc);
     1738            vrc = strAutoMountPoint.reserveNoThrow(cbStr);
     1739            AssertRCReturn(vrc, vrc);
     1740            vrc = SSMR3GetStrZ(pSSM, strAutoMountPoint.mutableRaw(), cbStr);
     1741            AssertRCReturn(vrc, vrc);
     1742            strAutoMountPoint.jolt();
     1743        }
    17321744
    17331745        ComObjPtr<SharedFolder> pSharedFolder;
     
    17381750                                         writable,
    17391751                                         autoMount,
     1752                                         strAutoMountPoint,
    17401753                                         false /* fFailOnError */);
    17411754        AssertComRCReturn(rc, VERR_INTERNAL_ERROR);
     
    29412954}
    29422955
    2943 HRESULT Console::createSharedFolder(const com::Utf8Str &aName, const com::Utf8Str &aHostPath, BOOL aWritable, BOOL aAutomount)
     2956HRESULT Console::createSharedFolder(const com::Utf8Str &aName, const com::Utf8Str &aHostPath, BOOL aWritable,
     2957                                    BOOL aAutomount, const com::Utf8Str &aAutoMountPoint)
    29442958{
    29452959    LogFlowThisFunc(("Entering for '%s' -> '%s'\n", aName.c_str(), aHostPath.c_str()));
     
    29742988                             !!aWritable,
    29752989                             !!aAutomount,
     2990                             aAutoMountPoint,
    29762991                             true /* fFailOnError */);
    29772992    if (FAILED(rc)) return rc;
     
    29953010
    29963011        /* second, create the given folder */
    2997         rc = i_createSharedFolder(aName, SharedFolderData(aHostPath, !!aWritable, !!aAutomount));
     3012        rc = i_createSharedFolder(aName, SharedFolderData(aHostPath, !!aWritable, !!aAutomount, aAutoMountPoint));
    29983013        if (FAILED(rc))
    29993014            return rc;
     
    76837698                sharedFolders[it->first] = SharedFolderData(pSF->i_getHostPath(),
    76847699                                                            pSF->i_isWritable(),
    7685                                                             pSF->i_isAutoMounted());
     7700                                                            pSF->i_isAutoMounted(),
     7701                                                            pSF->i_getAutoMountPoint());
    76867702            }
    76877703        }
     
    84418457                ComPtr<ISharedFolder> pSharedFolder = folders[i];
    84428458
    8443                 Bstr bstrName;
    8444                 Bstr bstrHostPath;
     8459                Bstr bstr;
     8460                rc = pSharedFolder->COMGETTER(Name)(bstr.asOutParam());
     8461                if (FAILED(rc)) throw rc;
     8462                Utf8Str strName(bstr);
     8463
     8464                rc = pSharedFolder->COMGETTER(HostPath)(bstr.asOutParam());
     8465                if (FAILED(rc)) throw rc;
     8466                Utf8Str strHostPath(bstr);
     8467
    84458468                BOOL writable;
    8446                 BOOL autoMount;
    8447 
    8448                 rc = pSharedFolder->COMGETTER(Name)(bstrName.asOutParam());
    8449                 if (FAILED(rc)) throw rc;
    8450                 Utf8Str strName(bstrName);
    8451 
    8452                 rc = pSharedFolder->COMGETTER(HostPath)(bstrHostPath.asOutParam());
    8453                 if (FAILED(rc)) throw rc;
    8454                 Utf8Str strHostPath(bstrHostPath);
    8455 
    84568469                rc = pSharedFolder->COMGETTER(Writable)(&writable);
    84578470                if (FAILED(rc)) throw rc;
    84588471
     8472                BOOL autoMount;
    84598473                rc = pSharedFolder->COMGETTER(AutoMount)(&autoMount);
    84608474                if (FAILED(rc)) throw rc;
    84618475
     8476                rc = pSharedFolder->COMGETTER(AutoMountPoint)(bstr.asOutParam());
     8477                if (FAILED(rc)) throw rc;
     8478                Utf8Str strAutoMountPoint(bstr);
     8479
    84628480                m_mapMachineSharedFolders.insert(std::make_pair(strName,
    8463                                                                 SharedFolderData(strHostPath, !!writable, !!autoMount)));
     8481                                                                SharedFolderData(strHostPath, !!writable,
     8482                                                                                 !!autoMount, strAutoMountPoint)));
    84648483
    84658484                /* send changes to HGCM if the VM is running */
     
    84888507                            /* create the new machine folder */
    84898508                            rc = i_createSharedFolder(strName,
    8490                                                       SharedFolderData(strHostPath, !!writable, !!autoMount));
     8509                                                      SharedFolderData(strHostPath, !!writable, !!autoMount, strAutoMountPoint));
    84918510                            if (FAILED(rc)) throw rc;
    84928511                        }
     
    85778596HRESULT Console::i_createSharedFolder(const Utf8Str &strName, const SharedFolderData &aData)
    85788597{
     8598    Log(("Adding shared folder '%s' -> '%s'\n", strName.c_str(), aData.m_strHostPath.c_str()));
     8599
     8600    /*
     8601     * Sanity checks
     8602     */
    85798603    ComAssertRet(strName.isNotEmpty(), E_FAIL);
    85808604    ComAssertRet(aData.m_strHostPath.isNotEmpty(), E_FAIL);
    85818605
    8582     /* sanity checks */
    85838606    AssertReturn(mpUVM, E_FAIL);
    85848607    AssertReturn(m_pVMMDev && m_pVMMDev->isShFlActive(), E_FAIL);
    85858608
    8586     VBOXHGCMSVCPARM parms[SHFL_CPARMS_ADD_MAPPING];
    8587     SHFLSTRING *pFolderName, *pMapName;
    8588     size_t cbString;
    8589 
    8590     Bstr value;
    8591     HRESULT hrc = mMachine->GetExtraData(BstrFmt("VBoxInternal2/SharedFoldersEnableSymlinksCreate/%s",
    8592                                                  strName.c_str()).raw(),
    8593                                          value.asOutParam());
    8594     bool fSymlinksCreate = hrc == S_OK && value == "1";
    8595 
    8596     Log(("Adding shared folder '%s' -> '%s'\n", strName.c_str(), aData.m_strHostPath.c_str()));
    8597 
    8598     // check whether the path is valid and exists
    8599     char hostPathFull[RTPATH_MAX];
    8600     int vrc = RTPathAbsEx(NULL,
    8601                           aData.m_strHostPath.c_str(),
    8602                           hostPathFull,
    8603                           sizeof(hostPathFull));
    8604 
    8605     bool fMissing = false;
     8609    /*
     8610     * Find out whether we should allow symbolic link creation.
     8611     */
     8612    Bstr bstrValue;
     8613    HRESULT hrc = mMachine->GetExtraData(BstrFmt("VBoxInternal2/SharedFoldersEnableSymlinksCreate/%s", strName.c_str()).raw(),
     8614                                         bstrValue.asOutParam());
     8615    bool fSymlinksCreate = hrc == S_OK && bstrValue == "1";
     8616
     8617    /*
     8618     * Check whether the path is valid and exists.
     8619     */
     8620    char szAbsHostPath[RTPATH_MAX];
     8621    int vrc = RTPathAbsEx(NULL, aData.m_strHostPath.c_str(), szAbsHostPath, sizeof(szAbsHostPath));
    86068622    if (RT_FAILURE(vrc))
    86078623        return setErrorBoth(E_INVALIDARG, vrc, tr("Invalid shared folder path: '%s' (%Rrc)"), aData.m_strHostPath.c_str(), vrc);
    8608     if (!RTPathExists(hostPathFull))
    8609         fMissing = true;
    8610 
    8611     /* Check whether the path is full (absolute) */
    8612     if (RTPathCompare(aData.m_strHostPath.c_str(), hostPathFull) != 0)
     8624
     8625    /* Check whether the path is full (absolute).  ASSUMING a RTPATH_MAX of ~4K
     8626       this also checks that the length is within bounds of a SHFLSTRING.  */
     8627    if (RTPathCompare(aData.m_strHostPath.c_str(), szAbsHostPath) != 0)
    86138628        return setError(E_INVALIDARG,
    86148629                        tr("Shared folder path '%s' is not absolute"),
    86158630                        aData.m_strHostPath.c_str());
    86168631
    8617     // now that we know the path is good, give it to HGCM
    8618 
    8619     Bstr bstrName(strName);
    8620     Bstr bstrHostPath(aData.m_strHostPath);
    8621 
    8622     cbString = (bstrHostPath.length() + 1) * sizeof(RTUTF16);
    8623     if (cbString >= UINT16_MAX)
    8624         return setError(E_INVALIDARG, tr("The name is too long"));
    8625     pFolderName = (SHFLSTRING*)RTMemAllocZ(SHFLSTRING_HEADER_SIZE + cbString);
    8626     Assert(pFolderName);
    8627     memcpy(pFolderName->String.ucs2, bstrHostPath.raw(), cbString);
    8628 
    8629     pFolderName->u16Size   = (uint16_t)cbString;
    8630     pFolderName->u16Length = (uint16_t)(cbString - sizeof(RTUTF16));
    8631 
    8632     parms[0].type = VBOX_HGCM_SVC_PARM_PTR;
    8633     parms[0].u.pointer.addr = pFolderName;
    8634     parms[0].u.pointer.size = ShflStringSizeOfBuffer(pFolderName);
    8635 
    8636     cbString = (bstrName.length() + 1) * sizeof(RTUTF16);
    8637     if (cbString >= UINT16_MAX)
    8638     {
    8639         RTMemFree(pFolderName);
    8640         return setError(E_INVALIDARG, tr("The host path is too long"));
    8641     }
    8642     pMapName = (SHFLSTRING*)RTMemAllocZ(SHFLSTRING_HEADER_SIZE + cbString);
    8643     Assert(pMapName);
    8644     memcpy(pMapName->String.ucs2, bstrName.raw(), cbString);
    8645 
    8646     pMapName->u16Size   = (uint16_t)cbString;
    8647     pMapName->u16Length = (uint16_t)(cbString - sizeof(RTUTF16));
    8648 
    8649     parms[1].type = VBOX_HGCM_SVC_PARM_PTR;
    8650     parms[1].u.pointer.addr = pMapName;
    8651     parms[1].u.pointer.size = ShflStringSizeOfBuffer(pMapName);
    8652 
    8653     parms[2].type = VBOX_HGCM_SVC_PARM_32BIT;
    8654     parms[2].u.uint32 = (aData.m_fWritable ? SHFL_ADD_MAPPING_F_WRITABLE : 0)
    8655                       | (aData.m_fAutoMount ? SHFL_ADD_MAPPING_F_AUTOMOUNT : 0)
    8656                       | (fSymlinksCreate ? SHFL_ADD_MAPPING_F_CREATE_SYMLINKS : 0)
    8657                       | (fMissing ? SHFL_ADD_MAPPING_F_MISSING : 0)
    8658                       ;
    8659 
    8660     vrc = m_pVMMDev->hgcmHostCall("VBoxSharedFolders",
    8661                                   SHFL_FN_ADD_MAPPING,
    8662                                   SHFL_CPARMS_ADD_MAPPING, &parms[0]);
    8663     RTMemFree(pFolderName);
    8664     RTMemFree(pMapName);
    8665 
    8666     if (RT_FAILURE(vrc))
    8667         return setErrorBoth(E_FAIL, vrc, tr("Could not create a shared folder '%s' mapped to '%s' (%Rrc)"),
    8668                             strName.c_str(), aData.m_strHostPath.c_str(), vrc);
    8669 
    8670     if (fMissing)
    8671         return setError(E_INVALIDARG,
    8672                         tr("Shared folder path '%s' does not exist on the host"),
    8673                         aData.m_strHostPath.c_str());
    8674 
    8675     return S_OK;
     8632    bool const fMissing = !RTPathExists(szAbsHostPath);
     8633
     8634    /*
     8635     * Check the other two string lengths before converting them all to SHFLSTRINGS.
     8636     */
     8637    if (strName.length() >= _2K)
     8638        return setError(E_INVALIDARG, tr("Shared folder name is too long: %zu bytes"), strName.length());
     8639    if (aData.m_strAutoMountPoint.length() >= RTPATH_MAX)
     8640        return setError(E_INVALIDARG, tr("Shared folder mountp point too long: %zu bytes"), aData.m_strAutoMountPoint.length());
     8641
     8642    PSHFLSTRING pHostPath       = ShflStringDupUtf8AsUtf16(aData.m_strHostPath.c_str());
     8643    PSHFLSTRING pName           = ShflStringDupUtf8AsUtf16(strName.c_str());
     8644    PSHFLSTRING pAutoMountPoint = ShflStringDupUtf8AsUtf16(aData.m_strAutoMountPoint.c_str());
     8645    if (pHostPath && pName && pAutoMountPoint)
     8646    {
     8647        /*
     8648         * Make a SHFL_FN_ADD_MAPPING call to tell the service about folder.
     8649         */
     8650        VBOXHGCMSVCPARM aParams[SHFL_CPARMS_ADD_MAPPING];
     8651        SHFLSTRING_TO_HGMC_PARAM(&aParams[0], pHostPath);
     8652        SHFLSTRING_TO_HGMC_PARAM(&aParams[1], pName);
     8653        aParams[2].setUInt32(  (aData.m_fWritable  ? SHFL_ADD_MAPPING_F_WRITABLE : 0)
     8654                             | (aData.m_fAutoMount ? SHFL_ADD_MAPPING_F_AUTOMOUNT : 0)
     8655                             | (fSymlinksCreate    ? SHFL_ADD_MAPPING_F_CREATE_SYMLINKS : 0)
     8656                             | (fMissing           ? SHFL_ADD_MAPPING_F_MISSING : 0));
     8657        SHFLSTRING_TO_HGMC_PARAM(&aParams[3], pAutoMountPoint);
     8658        AssertCompile(SHFL_CPARMS_ADD_MAPPING == 4);
     8659
     8660        vrc = m_pVMMDev->hgcmHostCall("VBoxSharedFolders", SHFL_FN_ADD_MAPPING, SHFL_CPARMS_ADD_MAPPING, aParams);
     8661        if (RT_FAILURE(vrc))
     8662            hrc = setErrorBoth(E_FAIL, vrc, tr("Could not create a shared folder '%s' mapped to '%s' (%Rrc)"),
     8663                               strName.c_str(), aData.m_strHostPath.c_str(), vrc);
     8664
     8665        else if (fMissing)
     8666            hrc = setError(E_INVALIDARG,
     8667                           tr("Shared folder path '%s' does not exist on the host"),
     8668                           aData.m_strHostPath.c_str());
     8669        else
     8670            hrc = S_OK;
     8671    }
     8672    else
     8673        hrc = E_OUTOFMEMORY;
     8674    RTMemFree(pAutoMountPoint);
     8675    RTMemFree(pName);
     8676    RTMemFree(pHostPath);
     8677    return hrc;
    86768678}
    86778679
     
    1017610178                 * Register our load/save state file handlers
    1017710179                 */
    10178                 vrc = SSMR3RegisterExternal(pConsole->mpUVM, sSSMConsoleUnit, 0 /*iInstance*/, sSSMConsoleVer, 0 /* cbGuess */,
     10180                vrc = SSMR3RegisterExternal(pConsole->mpUVM, sSSMConsoleUnit, 0 /*iInstance*/,
     10181                                            CONSOLE_SAVED_STATE_VERSION, 0 /* cbGuess */,
    1017910182                                            NULL, NULL, NULL,
    1018010183                                            NULL, i_saveStateFileExec, NULL,
  • trunk/src/VBox/Main/src-server/MachineImpl.cpp

    r75361 r75380  
    54225422}
    54235423
    5424 HRESULT Machine::createSharedFolder(const com::Utf8Str &aName, const com::Utf8Str &aHostPath, BOOL  aWritable, BOOL  aAutomount)
     5424HRESULT Machine::createSharedFolder(const com::Utf8Str &aName, const com::Utf8Str &aHostPath, BOOL aWritable,
     5425                                    BOOL aAutomount, const com::Utf8Str &aAutoMountPoint)
    54255426{
    54265427    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     
    54425443                            !!aWritable,
    54435444                            !!aAutomount,
     5445                            aAutoMountPoint,
    54445446                            true /* fFailOnError */);
    54455447    if (FAILED(rc)) return rc;
     
    90219023                                    RT_BOOL(sf.fWritable),
    90229024                                    RT_BOOL(sf.fAutoMount),
     9025                                    sf.strAutoMountPoint,
    90239026                                    false /* fFailOnError */);
    90249027            if (FAILED(rc)) return rc;
     
    1031610319            sf.fWritable = !!pSF->i_isWritable();
    1031710320            sf.fAutoMount = !!pSF->i_isAutoMounted();
     10321            sf.strAutoMountPoint = pSF->i_getAutoMountPoint();
    1031810322
    1031910323            data.llSharedFolders.push_back(sf);
  • trunk/src/VBox/Main/src-server/VirtualBoxImpl.cpp

    r73805 r75380  
    20132013                                       const com::Utf8Str &aHostPath,
    20142014                                       BOOL aWritable,
    2015                                        BOOL aAutomount)
     2015                                       BOOL aAutomount,
     2016                                       const com::Utf8Str &aAutoMountPoint)
    20162017{
    20172018    NOREF(aName);
     
    20192020    NOREF(aWritable);
    20202021    NOREF(aAutomount);
     2022    NOREF(aAutoMountPoint);
    20212023
    20222024    return setError(E_NOTIMPL, "Not yet implemented");
  • trunk/src/VBox/Main/xml/Settings.cpp

    r75361 r75380  
    28762876{
    28772877    return (this == &g)
    2878         || (   strName       == g.strName
    2879             && strHostPath   == g.strHostPath
    2880             && fWritable     == g.fWritable
    2881             && fAutoMount    == g.fAutoMount);
     2878        || (   strName           == g.strName
     2879            && strHostPath       == g.strHostPath
     2880            && fWritable         == g.fWritable
     2881            && fAutoMount        == g.fAutoMount
     2882            && strAutoMountPoint == g.strAutoMountPoint);
    28822883}
    28832884
     
    46994700                pelmFolder->getAttributeValue("writable", sf.fWritable);
    47004701                pelmFolder->getAttributeValue("autoMount", sf.fAutoMount);
     4702                pelmFolder->getAttributeValue("autoMountPoint", sf.strAutoMountPoint);
    47014703                hw.llSharedFolders.push_back(sf);
    47024704            }
     
    64596461            pelmThis->setAttribute("writable", sf.fWritable);
    64606462            pelmThis->setAttribute("autoMount", sf.fAutoMount);
     6463            if (sf.strAutoMountPoint.isNotEmpty())
     6464                pelmThis->setAttribute("autoMountPoint", sf.strAutoMountPoint);
    64616465        }
    64626466    }
     
    72927296            return;
    72937297        }
     7298        if (hardwareMachine.llSharedFolders.size())
     7299            for (SharedFoldersList::const_iterator it = hardwareMachine.llSharedFolders.begin();
     7300                 it != hardwareMachine.llSharedFolders.end();
     7301                 ++it)
     7302                if (it->strAutoMountPoint.isNotEmpty())
     7303                {
     7304                    m->sv = SettingsVersion_v1_17;
     7305                    return;
     7306                }
    72947307
    72957308        /*
Note: See TracChangeset for help on using the changeset viewer.

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