VirtualBox

Changeset 108046 in vbox for trunk


Ignore:
Timestamp:
Feb 4, 2025 5:24:54 AM (3 months ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
167323
Message:

doc/manual,include/VBox,Frontends/{VBoxManage,VirtualBox/src},Main/{include,SharedFolder,Console,Machine,VirtualBox,VirtualBox.xidl}: Added global shared folders and adjusted fetching and handling of folders between shared folder types bugref:3544

Location:
trunk
Files:
22 edited

Legend:

Unmodified
Added
Removed
  • trunk/doc/manual/en_US/man_VBoxManage-sharedfolder.xml

    r106061 r108046  
    5151      <command>VBoxManage sharedfolder add</command>
    5252      <group choice="req">
     53        <arg choice="plain">global</arg>
    5354        <arg choice="plain"><replaceable>uuid</replaceable></arg>
    5455        <arg choice="plain"><replaceable>vmname</replaceable></arg>
     
    6566      <command>VBoxManage sharedfolder remove</command>
    6667      <group choice="req">
     68        <arg choice="plain">global</arg>
    6769        <arg choice="plain"><replaceable>uuid</replaceable></arg>
    6870        <arg choice="plain"><replaceable>vmname</replaceable></arg>
     
    126128      <variablelist>
    127129        <varlistentry>
     130          <term><literal>global</literal></term>
     131          <listitem><para>
     132              Specifies that the share is global which means that it is
     133              available to all virtual machines.
     134            </para></listitem>
     135        </varlistentry>
     136        <varlistentry>
    128137          <term><option><replaceable>uuid</replaceable> | <replaceable>vmname</replaceable></option></term>
    129138          <listitem><para>
     
    203212      </para>
    204213      <variablelist>
     214        <varlistentry>
     215          <term><literal>global</literal></term>
     216          <listitem><para>
     217              Specifies that the share is global which means that it is
     218              accessible from all applicable guest VMs.
     219            </para></listitem>
     220        </varlistentry>
    205221        <varlistentry>
    206222          <term><option><replaceable>uuid</replaceable> | <replaceable>vmname</replaceable></option></term>
  • trunk/include/VBox/settings.h

    r107548 r108046  
    223223
    224224typedef std::list<NATHostLoopbackOffset> NATLoopbackOffsetList;
     225
     226/**
     227 * NOTE: If you add any fields in here, you must update a) the constructor and b)
     228 * the operator== which is used by MachineConfigFile::operator==(), or otherwise
     229 * your settings might never get saved.
     230 */
     231struct SharedFolder
     232{
     233    SharedFolder();
     234
     235    bool operator==(const SharedFolder &a) const;
     236
     237    com::Utf8Str    strName,
     238                    strHostPath;
     239    bool            fWritable;
     240    bool            fAutoMount;
     241    com::Utf8Str    strAutoMountPoint;
     242    SymlinkPolicy_T enmSymlinkPolicy;
     243};
     244
     245typedef std::list<SharedFolder> SharedFoldersList;
    225246
    226247typedef std::vector<uint8_t> IconBlob;
     
    513534    void readMachineRegistry(const xml::ElementNode &elmMachineRegistry);
    514535    void readNATNetworks(const xml::ElementNode &elmNATNetworks);
     536    void readSharedFolders(const xml::ElementNode &elmSharedFolders);
    515537#ifdef VBOX_WITH_VMNET
    516538    void readHostOnlyNetworks(const xml::ElementNode &elmHostOnlyNetworks);
     
    529551    DHCPServersList         llDhcpServers;
    530552    NATNetworksList         llNATNetworks;
     553    SharedFoldersList       llGlobalSharedFolders;
    531554#ifdef VBOX_WITH_VMNET
    532555    HostOnlyNetworksList    llHostOnlyNetworks;
     
    9971020    settings::StringsMap properties;
    9981021};
    999 
    1000 /**
    1001  * NOTE: If you add any fields in here, you must update a) the constructor and b)
    1002  * the operator== which is used by MachineConfigFile::operator==(), or otherwise
    1003  * your settings might never get saved.
    1004  */
    1005 struct SharedFolder
    1006 {
    1007     SharedFolder();
    1008 
    1009     bool operator==(const SharedFolder &a) const;
    1010 
    1011     com::Utf8Str    strName,
    1012                     strHostPath;
    1013     bool            fWritable;
    1014     bool            fAutoMount;
    1015     com::Utf8Str    strAutoMountPoint;
    1016     SymlinkPolicy_T enmSymlinkPolicy;
    1017 };
    1018 
    1019 typedef std::list<SharedFolder> SharedFoldersList;
    10201022
    10211023/**
  • trunk/src/VBox/Frontends/VBoxManage/VBoxManageInfo.cpp

    r108003 r108046  
    27932793        RTPrintf("%-28s ", Info::tr("Shared folders:"));
    27942794    uint32_t numSharedFolders = 0;
    2795 #if 0 // not yet implemented
    27962795    /* globally shared folders first */
    27972796    {
    2798         SafeIfaceArray <ISharedFolder> sfColl;
    2799         CHECK_ERROR_RET(pVirtualBox, COMGETTER(SharedFolders)(ComSafeArrayAsOutParam(sfColl)), rc);
    2800         for (size_t i = 0; i < sfColl.size(); ++i)
    2801         {
    2802             ComPtr<ISharedFolder> sf = sfColl[i];
     2797        com::SafeIfaceArray <ISharedFolder> folders;
     2798        CHECK_ERROR_RET(pVirtualBox, COMGETTER(SharedFolders)(ComSafeArrayAsOutParam(folders)), hrc);
     2799        for (size_t i = 0; i < folders.size(); ++i)
     2800        {
     2801            ComPtr<ISharedFolder> sf = folders[i];
    28032802            showSharedFolder(sf, details, Info::tr("global mapping"), "GlobalMapping", i + 1, numSharedFolders == 0);
    28042803            ++numSharedFolders;
    28052804        }
    28062805    }
    2807 #endif
    28082806    /* now VM mappings */
    28092807    {
  • trunk/src/VBox/Frontends/VBoxManage/VBoxManageMisc.cpp

    r108003 r108046  
    16871687     * Done parsing, do some work.
    16881688     */
    1689     ComPtr<IMachine> ptrMachine;
    1690     CHECK_ERROR2I_RET(a->virtualBox, FindMachine(Bstr(pszMachineName).raw(), ptrMachine.asOutParam()), RTEXITCODE_FAILURE);
    1691     AssertReturn(ptrMachine.isNotNull(), RTEXITCODE_FAILURE);
    1692 
    16931689    HRESULT hrc;
    1694     if (fTransient)
    1695     {
    1696         /* open an existing session for the VM */
    1697         CHECK_ERROR2I_RET(ptrMachine, LockMachine(a->session, LockType_Shared), RTEXITCODE_FAILURE);
    1698 
    1699         /* get the session machine */
    1700         ComPtr<IMachine> ptrSessionMachine;
    1701         CHECK_ERROR2I_RET(a->session, COMGETTER(Machine)(ptrSessionMachine.asOutParam()), RTEXITCODE_FAILURE);
    1702 
    1703         /* get the session console */
    1704         ComPtr<IConsole> ptrConsole;
    1705         CHECK_ERROR2I_RET(a->session, COMGETTER(Console)(ptrConsole.asOutParam()), RTEXITCODE_FAILURE);
    1706         if (ptrConsole.isNull())
    1707             return RTMsgErrorExit(RTEXITCODE_FAILURE, Misc::tr("Machine '%s' is not currently running."), pszMachineName);
    1708 
    1709         CHECK_ERROR2(hrc, ptrConsole, CreateSharedFolder(Bstr(pszName).raw(), Bstr(szAbsHostPath).raw(),
    1710                                                          fWritable, fAutoMount, Bstr(pszAutoMountPoint).raw()));
    1711         a->session->UnlockMachine();
     1690    if (!strcmp(pszMachineName, "global"))
     1691    {
     1692        if (fTransient)
     1693            return errorSyntax(Misc::tr("Invalid option: global and transient both specified"));
     1694        ComPtr<IVirtualBox> pVirtualBox = a->virtualBox;
     1695        CHECK_ERROR2(hrc, pVirtualBox, CreateSharedFolder(Bstr(pszName).raw(), Bstr(szAbsHostPath).raw(),
     1696                                                          fWritable, fAutoMount, Bstr(pszAutoMountPoint).raw()));
    17121697    }
    17131698    else
    17141699    {
    1715         /* open a session for the VM */
    1716         CHECK_ERROR2I_RET(ptrMachine, LockMachine(a->session, LockType_Write), RTEXITCODE_FAILURE);
    1717 
    1718         /* get the mutable session machine */
    1719         ComPtr<IMachine> ptrSessionMachine;
    1720         CHECK_ERROR2I_RET(a->session, COMGETTER(Machine)(ptrSessionMachine.asOutParam()), RTEXITCODE_FAILURE);
    1721 
    1722         CHECK_ERROR2(hrc, ptrSessionMachine, CreateSharedFolder(Bstr(pszName).raw(), Bstr(szAbsHostPath).raw(),
    1723                                                                 fWritable, fAutoMount, Bstr(pszAutoMountPoint).raw()));
    1724         if (SUCCEEDED(hrc))
    1725         {
    1726             CHECK_ERROR2(hrc, ptrSessionMachine, SaveSettings());
    1727         }
    1728 
    1729         a->session->UnlockMachine();
     1700        ComPtr<IMachine> ptrMachine;
     1701        CHECK_ERROR2I_RET(a->virtualBox, FindMachine(Bstr(pszMachineName).raw(), ptrMachine.asOutParam()), RTEXITCODE_FAILURE);
     1702        AssertReturn(ptrMachine.isNotNull(), RTEXITCODE_FAILURE);
     1703
     1704        if (fTransient)
     1705        {
     1706            /* open an existing session for the VM */
     1707            CHECK_ERROR2I_RET(ptrMachine, LockMachine(a->session, LockType_Shared), RTEXITCODE_FAILURE);
     1708
     1709            /* get the session machine */
     1710            ComPtr<IMachine> ptrSessionMachine;
     1711            CHECK_ERROR2I_RET(a->session, COMGETTER(Machine)(ptrSessionMachine.asOutParam()), RTEXITCODE_FAILURE);
     1712
     1713            /* get the session console */
     1714            ComPtr<IConsole> ptrConsole;
     1715            CHECK_ERROR2I_RET(a->session, COMGETTER(Console)(ptrConsole.asOutParam()), RTEXITCODE_FAILURE);
     1716            if (ptrConsole.isNull())
     1717                return RTMsgErrorExit(RTEXITCODE_FAILURE, Misc::tr("Machine '%s' is not currently running."), pszMachineName);
     1718
     1719            CHECK_ERROR2(hrc, ptrConsole, CreateSharedFolder(Bstr(pszName).raw(), Bstr(szAbsHostPath).raw(),
     1720                                                             fWritable, fAutoMount, Bstr(pszAutoMountPoint).raw()));
     1721            a->session->UnlockMachine();
     1722        }
     1723        else
     1724        {
     1725            /* open a session for the VM */
     1726            CHECK_ERROR2I_RET(ptrMachine, LockMachine(a->session, LockType_Write), RTEXITCODE_FAILURE);
     1727
     1728            /* get the mutable session machine */
     1729            ComPtr<IMachine> ptrSessionMachine;
     1730            CHECK_ERROR2I_RET(a->session, COMGETTER(Machine)(ptrSessionMachine.asOutParam()), RTEXITCODE_FAILURE);
     1731
     1732            CHECK_ERROR2(hrc, ptrSessionMachine, CreateSharedFolder(Bstr(pszName).raw(), Bstr(szAbsHostPath).raw(),
     1733                                                                    fWritable, fAutoMount, Bstr(pszAutoMountPoint).raw()));
     1734            if (SUCCEEDED(hrc))
     1735            {
     1736                CHECK_ERROR2(hrc, ptrSessionMachine, SaveSettings());
     1737            }
     1738
     1739            a->session->UnlockMachine();
     1740        }
    17301741    }
    17311742
     
    17851796     * Done parsing, do some real work.
    17861797     */
    1787     ComPtr<IMachine> ptrMachine;
    1788     CHECK_ERROR2I_RET(a->virtualBox, FindMachine(Bstr(pszMachineName).raw(), ptrMachine.asOutParam()), RTEXITCODE_FAILURE);
    1789     AssertReturn(ptrMachine.isNotNull(), RTEXITCODE_FAILURE);
    1790 
    17911798    HRESULT hrc;
    1792     if (fTransient)
    1793     {
    1794         /* open an existing session for the VM */
    1795         CHECK_ERROR2I_RET(ptrMachine, LockMachine(a->session, LockType_Shared), RTEXITCODE_FAILURE);
    1796         /* get the session machine */
    1797         ComPtr<IMachine> ptrSessionMachine;
    1798         CHECK_ERROR2I_RET(a->session, COMGETTER(Machine)(ptrSessionMachine.asOutParam()), RTEXITCODE_FAILURE);
    1799         /* get the session console */
    1800         ComPtr<IConsole> ptrConsole;
    1801         CHECK_ERROR2I_RET(a->session, COMGETTER(Console)(ptrConsole.asOutParam()), RTEXITCODE_FAILURE);
    1802         if (ptrConsole.isNull())
    1803             return RTMsgErrorExit(RTEXITCODE_FAILURE, Misc::tr("Machine '%s' is not currently running.\n"), pszMachineName);
    1804 
    1805         CHECK_ERROR2(hrc, ptrConsole, RemoveSharedFolder(Bstr(pszName).raw()));
    1806 
    1807         a->session->UnlockMachine();
     1799    if (!strcmp(pszMachineName, "global"))
     1800    {
     1801        ComPtr<IVirtualBox> pVirtualBox = a->virtualBox;
     1802        CHECK_ERROR2(hrc, pVirtualBox, RemoveSharedFolder(Bstr(pszName).raw()));
    18081803    }
    18091804    else
    18101805    {
    1811         /* open a session for the VM */
    1812         CHECK_ERROR2I_RET(ptrMachine, LockMachine(a->session, LockType_Write), RTEXITCODE_FAILURE);
    1813 
    1814         /* get the mutable session machine */
    1815         ComPtr<IMachine> ptrSessionMachine;
    1816         CHECK_ERROR2I_RET(a->session, COMGETTER(Machine)(ptrSessionMachine.asOutParam()), RTEXITCODE_FAILURE);
    1817 
    1818         CHECK_ERROR2(hrc, ptrSessionMachine, RemoveSharedFolder(Bstr(pszName).raw()));
    1819 
    1820         /* commit and close the session */
    1821         if (SUCCEEDED(hrc))
    1822         {
    1823             CHECK_ERROR2(hrc, ptrSessionMachine, SaveSettings());
    1824         }
    1825         a->session->UnlockMachine();
     1806        ComPtr<IMachine> ptrMachine;
     1807        CHECK_ERROR2I_RET(a->virtualBox, FindMachine(Bstr(pszMachineName).raw(), ptrMachine.asOutParam()), RTEXITCODE_FAILURE);
     1808        AssertReturn(ptrMachine.isNotNull(), RTEXITCODE_FAILURE);
     1809
     1810        if (fTransient)
     1811        {
     1812            /* open an existing session for the VM */
     1813            CHECK_ERROR2I_RET(ptrMachine, LockMachine(a->session, LockType_Shared), RTEXITCODE_FAILURE);
     1814            /* get the session machine */
     1815            ComPtr<IMachine> ptrSessionMachine;
     1816            CHECK_ERROR2I_RET(a->session, COMGETTER(Machine)(ptrSessionMachine.asOutParam()), RTEXITCODE_FAILURE);
     1817            /* get the session console */
     1818            ComPtr<IConsole> ptrConsole;
     1819            CHECK_ERROR2I_RET(a->session, COMGETTER(Console)(ptrConsole.asOutParam()), RTEXITCODE_FAILURE);
     1820            if (ptrConsole.isNull())
     1821                return RTMsgErrorExit(RTEXITCODE_FAILURE, Misc::tr("Machine '%s' is not currently running.\n"), pszMachineName);
     1822
     1823            CHECK_ERROR2(hrc, ptrConsole, RemoveSharedFolder(Bstr(pszName).raw()));
     1824
     1825            a->session->UnlockMachine();
     1826        }
     1827        else
     1828        {
     1829            /* open a session for the VM */
     1830            CHECK_ERROR2I_RET(ptrMachine, LockMachine(a->session, LockType_Write), RTEXITCODE_FAILURE);
     1831
     1832            /* get the mutable session machine */
     1833            ComPtr<IMachine> ptrSessionMachine;
     1834            CHECK_ERROR2I_RET(a->session, COMGETTER(Machine)(ptrSessionMachine.asOutParam()), RTEXITCODE_FAILURE);
     1835
     1836            CHECK_ERROR2(hrc, ptrSessionMachine, RemoveSharedFolder(Bstr(pszName).raw()));
     1837
     1838            /* commit and close the session */
     1839            if (SUCCEEDED(hrc))
     1840            {
     1841                CHECK_ERROR2(hrc, ptrSessionMachine, SaveSettings());
     1842            }
     1843            a->session->UnlockMachine();
     1844        }
    18261845    }
    18271846
  • trunk/src/VBox/Frontends/VBoxShell/vboxshell.py

    r106061 r108046  
    16191619    print("Machines: %s" % (colPath(ctx, props.defaultMachineFolder)))
    16201620
    1621     #print("Global shared folders:")
    1622     #for ud in ctx['global'].getArray(vbox, 'sharedFolders'):
    1623     #    printSf(ctx, sf)
     1621    print("Global shared folders:")
     1622    for sf in ctx['global'].getArray(vbox, 'sharedFolders'):
     1623        printSf(ctx, sf)
    16241624    host = vbox.host
    16251625    cnt = host.processorCount
     
    26482648        return 0
    26492649
    2650     mach = argsToMach(ctx, args)
    2651     if mach is None:
    2652         return 0
     2650    if args[1] != 'global':
     2651        mach = argsToMach(ctx, args)
     2652        if mach is None:
     2653            return 0
    26532654    path = args[2]
    26542655    name = args[3]
     
    26612662            if cur_arg == 'persistent':
    26622663                persistent = True
    2663     if persistent:
     2664    if args[1] == 'global':
     2665        ctx['vb'].createSharedFolder(name, path, writable)
     2666    elif persistent:
    26642667        cmdClosedVm(ctx, mach, lambda ctx, mach, args: mach.createSharedFolder(name, path, writable), [])
    26652668    else:
     
    26722675        return 0
    26732676
    2674     mach = argsToMach(ctx, args)
    2675     if mach is None:
    2676         return 0
     2677    if args[1] != 'global':
     2678        mach = argsToMach(ctx, args)
     2679        if mach is None:
     2680            return 0
    26772681    name = args[2]
    26782682    found = False
    2679     for sharedfolder in ctx['global'].getArray(mach, 'sharedFolders'):
    2680         if sharedfolder.name == name:
    2681             cmdClosedVm(ctx, mach, lambda ctx, mach, args: mach.removeSharedFolder(name), [])
    2682             found = True
    2683             break
    2684     if not found:
    2685         cmdExistingVm(ctx, mach, 'guestlambda', [lambda ctx, mach, console, args: console.removeSharedFolder(name)])
     2683    if args[1] == 'global':
     2684        for sharedfolder in ctx['global'].getArray(ctx['vb'], 'sharedFolders'):
     2685            if sharedfolder.name == name:
     2686                ctx['vb'].removeSharedFolder(name)
     2687                found = True
     2688                break
     2689    else:
     2690        for sharedfolder in ctx['global'].getArray(mach, 'sharedFolders'):
     2691            if sharedfolder.name == name:
     2692                cmdClosedVm(ctx, mach, lambda ctx, mach, args: mach.removeSharedFolder(name), [])
     2693                found = True
     2694                break
     2695        if not found:
     2696            cmdExistingVm(ctx, mach, 'guestlambda', [lambda ctx, mach, console, args: console.removeSharedFolder(name)])
    26862697    return 0
    26872698
  • trunk/src/VBox/Frontends/VirtualBox/src/extradata/UIExtraDataDefs.h

    r107330 r108046  
    896896enum UISharedFolderType
    897897{
     898    UISharedFolderType_Global,
    898899    UISharedFolderType_Machine,
    899900    UISharedFolderType_Console
  • trunk/src/VBox/Frontends/VirtualBox/src/globals/UIDetailsGenerator.cpp

    r106061 r108046  
    14111411    /* Enumerate all the folders: */
    14121412    QMap<QString, QString> folders;
     1413    foreach (const CSharedFolder &comGlobalFolder, gpGlobalSession->virtualBox().GetSharedFolders())
     1414        folders.insert(comGlobalFolder.GetName(), comGlobalFolder.GetHostPath());
    14131415    foreach (const CSharedFolder &comPermanentFolder, comMachine.GetSharedFolders())
    14141416        folders.insert(comPermanentFolder.GetName(), comPermanentFolder.GetHostPath());
  • trunk/src/VBox/Frontends/VirtualBox/src/settings/editors/UISharedFolderDetailsEditor.cpp

    r106061 r108046  
    5757    , m_pCheckBoxAutoMount(0)
    5858    , m_pCheckBoxPermanent(0)
     59    , m_pCheckBoxGlobal(0)
    5960    , m_pButtonBox(0)
    6061{
     
    115116{
    116117    return m_pEditorAutoMountPoint ? m_pEditorAutoMountPoint->text() : QString();
     118}
     119
     120void UISharedFolderDetailsEditor::setGlobal(bool fGlobal)
     121{
     122    if (m_pCheckBoxGlobal)
     123        m_pCheckBoxGlobal->setChecked(fGlobal);
     124}
     125
     126bool UISharedFolderDetailsEditor::isGlobal() const
     127{
     128    return m_pCheckBoxGlobal ? m_pCheckBoxGlobal->isChecked() : false;
    117129}
    118130
     
    171183    if (m_pCheckBoxPermanent)
    172184    {
    173         m_pCheckBoxPermanent->setText(tr("&Make Permanent"));
    174         m_pCheckBoxPermanent->setToolTip(tr("When checked, this shared folder will be permanent."));
    175     }
     185        m_pCheckBoxPermanent->setText(tr("&Make Machine-permanent"));
     186        m_pCheckBoxPermanent->setToolTip(tr("When checked, this shared folder will be permanent "
     187                                            "to this guest machine."));
     188    }
     189    if (m_pCheckBoxGlobal)
     190    {
     191        m_pCheckBoxGlobal->setText(tr("&Make Global"));
     192        m_pCheckBoxGlobal->setToolTip(tr("When checked, this shared folder will be available "
     193                                         "to all VMs."));
     194    }
     195}
     196
     197void UISharedFolderDetailsEditor::sltGlobalToggled()
     198{
     199    m_pCheckBoxPermanent->setHidden(m_pCheckBoxGlobal->isChecked());
    176200}
    177201
     
    253277    if (pLayout)
    254278    {
    255         pLayout->setRowStretch(6, 1);
     279        pLayout->setRowStretch(7, 1);
    256280
    257281        /* Prepare path label: */
     
    311335            pLayout->addWidget(m_pCheckBoxPermanent, 5, 1);
    312336        }
     337        /* Prepare global check-box: */
     338        m_pCheckBoxGlobal = new QCheckBox(this);
     339        if (m_pCheckBoxGlobal)
     340        {
     341            pLayout->addWidget(m_pCheckBoxGlobal, 6, 1);
     342        }
    313343
    314344        /* Prepare button-box: */
     
    317347        {
    318348            m_pButtonBox->setStandardButtons(QDialogButtonBox::Cancel | QDialogButtonBox::Ok);
    319             pLayout->addWidget(m_pButtonBox, 7, 0, 1, 2);
     349            pLayout->addWidget(m_pButtonBox, 8, 0, 1, 2);
    320350        }
    321351    }
     
    335365                this, &UISharedFolderDetailsEditor::sltValidate);
    336366    if (m_fUsePermanent)
     367    {
    337368        connect(m_pCheckBoxPermanent, &QCheckBox::toggled,
    338369                this, &UISharedFolderDetailsEditor::sltValidate);
     370        connect(m_pCheckBoxGlobal, &QCheckBox::toggled,
     371                this, &UISharedFolderDetailsEditor::sltGlobalToggled);
     372    }
    339373    if (m_pButtonBox)
    340374    {
  • trunk/src/VBox/Frontends/VirtualBox/src/settings/editors/UISharedFolderDetailsEditor.h

    r106061 r108046  
    9595    bool isPermanent() const;
    9696
     97    /** Defines whether folder is @a fGlobal. */
     98    void setGlobal(bool fGlobal);
     99    /** Returns whether folder is global. */
     100    bool isGlobal() const;
     101
    97102private slots:
    98103
    99104    /** Handles translation event. */
    100105    void sltRetranslateUI();
     106    /** Handles global/machine folder button visibility. */
     107    void sltGlobalToggled();
    101108    /** Holds signal about folder path selected. */
    102109    void sltSelectPath();
     
    143150        /** Holds the permanent check-box instance. */
    144151        QCheckBox          *m_pCheckBoxPermanent;
     152        /** Holds the global check-box instance. */
     153        QCheckBox          *m_pCheckBoxGlobal;
    145154        /** Holds the button-box instance. */
    146155        QIDialogButtonBox  *m_pButtonBox;
  • trunk/src/VBox/Frontends/VirtualBox/src/settings/editors/UISharedFoldersEditor.cpp

    r106061 r108046  
    466466    const bool fAddEnabled = pCurrentItem;
    467467    const bool fRemoveEnabled = fAddEnabled && pCurrentItem->parent();
     468    SFTreeViewItem *pItem = static_cast<SFTreeViewItem*>(pCurrentItem);
     469    const bool fEditEnabled = fRemoveEnabled && pItem->m_enmType != UISharedFolderType_Global;
    468470    m_pActionAdd->setEnabled(fAddEnabled);
    469     m_pActionEdit->setEnabled(fRemoveEnabled);
     471    m_pActionEdit->setEnabled(fEditEnabled);
    470472    m_pActionRemove->setEnabled(fRemoveEnabled);
    471473}
     
    473475void UISharedFoldersEditor::sltHandleDoubleClick(QTreeWidgetItem *pItem)
    474476{
    475     const bool fEditEnabled = pItem && pItem->parent();
     477    SFTreeViewItem *pSFItem = static_cast<SFTreeViewItem*>(pItem);
     478    const bool fEditEnabled =    pItem
     479                              && pItem->parent()
     480                              && pSFItem->m_enmType != UISharedFolderType_Global;
    476481    if (fEditEnabled)
    477482        sltEditFolder();
     
    484489    if (m_pTreeWidget->isEnabled() && pItem && pItem->flags() & Qt::ItemIsSelectable)
    485490    {
    486         menu.addAction(m_pActionEdit);
     491        SFTreeViewItem *pSFItem = static_cast<SFTreeViewItem*>(pItem);
     492        if (pSFItem->m_enmType != UISharedFolderType_Global)
     493            menu.addAction(m_pActionEdit);
    487494        menu.addAction(m_pActionRemove);
    488495    }
     
    508515        const QString strName = dlgFolderDetails.name();
    509516        const QString strPath = dlgFolderDetails.path();
    510         const UISharedFolderType enmType = dlgFolderDetails.isPermanent() ? UISharedFolderType_Machine : UISharedFolderType_Console;
     517        const UISharedFolderType enmType =   dlgFolderDetails.isGlobal()
     518                                           ? UISharedFolderType_Global
     519                                           : dlgFolderDetails.isPermanent()
     520                                           ? UISharedFolderType_Machine
     521                                           : UISharedFolderType_Console;
    511522        /* Shared folder's name & path could not be empty: */
    512523        Assert(!strName.isEmpty() && !strPath.isEmpty());
     
    546557    dlgFolderDetails.setName(pItem->m_strName);
    547558    dlgFolderDetails.setPermanent(pItem->m_enmType == UISharedFolderType_Machine);
     559    dlgFolderDetails.setGlobal(pItem->m_enmType == UISharedFolderType_Global);
    548560    dlgFolderDetails.setWriteable(pItem->m_fWritable);
    549561    dlgFolderDetails.setAutoMount(pItem->m_fAutoMount);
     
    555567        const QString strName = dlgFolderDetails.name();
    556568        const QString strPath = dlgFolderDetails.path();
    557         const UISharedFolderType enmType = dlgFolderDetails.isPermanent() ? UISharedFolderType_Machine : UISharedFolderType_Console;
     569        const UISharedFolderType enmType =   dlgFolderDetails.isGlobal()
     570                                           ? UISharedFolderType_Global
     571                                           : dlgFolderDetails.isPermanent()
     572                                           ? UISharedFolderType_Machine
     573                                           : UISharedFolderType_Console;
    558574        /* Shared folder's name & path could not be empty: */
    559575        Assert(!strName.isEmpty() && !strPath.isEmpty());
     
    751767            switch (enmSharedFolderType)
    752768            {
     769                case UISharedFolderType_Global: pRootItem->m_strName = tr(" Global Folders"); break;
    753770                case UISharedFolderType_Machine: pRootItem->m_strName = tr(" Machine Folders"); break;
    754771                case UISharedFolderType_Console: pRootItem->m_strName = tr(" Transient Folders"); break;
     
    766783void UISharedFoldersEditor::updateRootItemsVisibility()
    767784{
     785    /* Update (show/hide) global root item: */
     786    setRootItemVisible(UISharedFolderType_Global, m_foldersAvailable.value(UISharedFolderType_Global));
    768787    /* Update (show/hide) machine (permanent) root item: */
    769788    setRootItemVisible(UISharedFolderType_Machine, m_foldersAvailable.value(UISharedFolderType_Machine));
  • trunk/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsSF.cpp

    r107478 r108046  
    3131/* GUI includes: */
    3232#include "UIErrorString.h"
     33#include "UIGlobalSession.h"
    3334#include "UIMachineSettingsSF.h"
    3435#include "UISharedFoldersEditor.h"
     
    106107    /* Get actual folders: */
    107108    QMultiMap<UISharedFolderType, CSharedFolder> folders;
     109    /* Load global folders: */
     110    if (isSharedFolderTypeSupported(UISharedFolderType_Global))
     111    {
     112        foreach (const CSharedFolder &folder, getSharedFolders(UISharedFolderType_Global))
     113            folders.insert(UISharedFolderType_Global, folder);
     114    }
    108115    /* Load machine (permanent) folders if allowed: */
    109116    if (isSharedFolderTypeSupported(UISharedFolderType_Machine))
     
    215222    /* Polish availability: */
    216223    m_pEditorSharedFolders->setFeatureAvailable(isMachineInValidMode());
     224    m_pEditorSharedFolders->setFoldersAvailable(UISharedFolderType_Global, isSharedFolderTypeSupported(UISharedFolderType_Global));
    217225    m_pEditorSharedFolders->setFoldersAvailable(UISharedFolderType_Machine, isSharedFolderTypeSupported(UISharedFolderType_Machine));
    218226    m_pEditorSharedFolders->setFoldersAvailable(UISharedFolderType_Console, isSharedFolderTypeSupported(UISharedFolderType_Console));
     
    264272    switch (enmSharedFolderType)
    265273    {
     274        case UISharedFolderType_Global: return true;
    266275        case UISharedFolderType_Machine: return isMachineInValidMode();
    267276        case UISharedFolderType_Console: return isMachineOnline();
     
    289298        switch (enmFoldersType)
    290299        {
     300            case UISharedFolderType_Global:
     301            {
     302                /* Load global folders: */
     303                CVirtualBox vbox = gpGlobalSession->virtualBox();
     304                folders = vbox.GetSharedFolders();
     305                fSuccess = vbox.isOk();
     306
     307                /* Show error message if necessary: */
     308                if (!fSuccess)
     309                    notifyOperationProgressError(UIErrorString::formatErrorInfo(vbox));
     310
     311                break;
     312            }
    291313            case UISharedFolderType_Machine:
    292314            {
     
    413435            switch (enmFoldersType)
    414436            {
     437                case UISharedFolderType_Global:
     438                {
     439                    /* Remove existing folder: */
     440                    CVirtualBox vbox = gpGlobalSession->virtualBox();
     441                    vbox.RemoveSharedFolder(strFolderName);
     442                    fSuccess = vbox.isOk();
     443                    if (!fSuccess)
     444                    {
     445                        /* Show error message: */
     446                        notifyOperationProgressError(UIErrorString::formatErrorInfo(vbox));
     447                    }
     448                    break;
     449                }
    415450                case UISharedFolderType_Machine:
    416451                {
     
    474509        switch (enmFoldersType)
    475510        {
     511            case UISharedFolderType_Global:
     512            {
     513                /* Create new folder: */
     514                CVirtualBox vbox = gpGlobalSession->virtualBox();
     515                vbox.CreateSharedFolder(strFolderName, strFolderPath, fIsWritable, fIsAutoMount, strAutoMountPoint);
     516                /* Show error if the operation failed: */
     517                fSuccess = vbox.isOk();
     518                if (!fSuccess)
     519                    notifyOperationProgressError(UIErrorString::formatErrorInfo(vbox));
     520                break;
     521            }
    476522            case UISharedFolderType_Machine:
    477523            {
  • trunk/src/VBox/Main/idl/VirtualBox.xidl

    r107930 r108046  
    27642764  <interface
    27652765    name="IVirtualBox" extends="$unknown"
    2766     uuid="d644ad1e-c501-4fc7-9ab6-aa6d763bc540"
     2766    uuid="2ce10519-3c09-45d8-a12d-e887786146b7"
    27672767    wsmap="managed"
    27682768    rest="managed"
     
    29522952        <link to="#createSharedFolder"/>. Existing shared folders can be
    29532953        removed using <link to="#removeSharedFolder"/>.
    2954 
    2955         <note>
    2956           In the current version of the product, global shared folders are not
    2957           implemented and therefore this collection is always empty.
    2958         </note>
    29592954      </desc>
    29602955    </attribute>
     
    36303625        folders and starts sharing it. Refer to the description of
    36313626        <link to="ISharedFolder"/> to read more about logical names.
    3632         <note>
    3633           In the current implementation, this operation is not
    3634           implemented.
    3635         </note>
     3627
     3628        <result name="VBOX_E_OBJECT_IN_USE">
     3629          Shared folder already exists.
     3630        </result>
     3631        <result name="VBOX_E_FILE_ERROR">
     3632          Shared folder @a hostPath not accessible.
     3633        </result>
     3634
    36363635      </desc>
    36373636      <param name="name" type="wstring" dir="in">
     
    36623661        created by <link to="#createSharedFolder"/> from the collection of
    36633662        shared folders and stops sharing it.
    3664         <note>
    3665           In the current implementation, this operation is not
    3666           implemented.
    3667         </note>
     3663
     3664        <result name="VBOX_E_OBJECT_NOT_FOUND">
     3665          Shared folder @a name does not exist.
     3666        </result>
     3667
    36683668      </desc>
    36693669      <param name="name" type="wstring" dir="in">
     
    2471724717      are in different name spaces, so they don't overlap and don't need to
    2471824718      have unique logical names.
    24719 
    24720       <note>
    24721         Global shared folders are not implemented in the current version of the
    24722         product.
    24723       </note>
    2472424719    </desc>
    2472524720
  • trunk/src/VBox/Main/include/ConsoleSharedFolderImpl.h

    r106061 r108046  
    5353    HRESULT init(Console *aConsole, const com::Utf8Str &aName, const com::Utf8Str &aHostPath,
    5454                 bool aWritable, bool aAutoMount, const com::Utf8Str &aAutoMountPoint, bool fFailOnError);
    55 //     HRESULT init(VirtualBox *aVirtualBox, const Utf8Str &aName, const Utf8Str &aHostPath,
    56 //                  bool aWritable, const com::Utf8Str &aAutoMountPoint, bool aAutoMount, bool fFailOnError);
     55//  HRESULT init(VirtualBox *aVirtualBox, const Utf8Str &aName, const Utf8Str &aHostPath,
     56//               bool aWritable, bool aAutoMount, const com::Utf8Str &aAutoMountPoint, bool fFailOnError);
    5757    void uninit();
    5858
  • trunk/src/VBox/Main/include/MachineImpl.h

    r107526 r108046  
    566566    virtual HRESULT i_onCPUExecutionCapChange(ULONG /* aExecutionCap */) { return S_OK; }
    567567    virtual HRESULT i_onMediumChange(IMediumAttachment * /* mediumAttachment */, BOOL /* force */) { return S_OK; }
    568     virtual HRESULT i_onSharedFolderChange() { return S_OK; }
     568    virtual HRESULT i_onSharedFolderChange(BOOL /* aGlobal */) { return S_OK; }
    569569    virtual HRESULT i_onVMProcessPriorityChange(VMProcPriority_T /* aPriority */) { return S_OK; }
    570570    virtual HRESULT i_onClipboardModeChange(ClipboardMode_T /* aClipboardMode */) { return S_OK; }
     
    14081408    HRESULT i_onUSBDeviceDetach(IN_BSTR aId,
    14091409                                IVirtualBoxErrorInfo *aError);
    1410     HRESULT i_onSharedFolderChange() RT_OVERRIDE;
     1410    HRESULT i_onSharedFolderChange(BOOL aGlobal) RT_OVERRIDE;
    14111411    HRESULT i_onClipboardModeChange(ClipboardMode_T aClipboardMode) RT_OVERRIDE;
    14121412    HRESULT i_onClipboardFileTransferModeChange(BOOL aEnable) RT_OVERRIDE;
  • trunk/src/VBox/Main/include/SharedFolderImpl.h

    r106061 r108046  
    3737class Console;
    3838
     39namespace settings
     40{
     41    struct SharedFolder;
     42}
     43
    3944class ATL_NO_VTABLE SharedFolder :
    4045    public SharedFolderWrap
     
    5459//    HRESULT init(Console *aConsole, const com::Utf8Str &aName, const com::Utf8Str &aHostPath,
    5560//                 bool aWritable, bool aAutoMount, const com::Utf8Str &aAutoMountPoint, bool fFailOnError);
    56 //     HRESULT init(VirtualBox *aVirtualBox, const Utf8Str &aName, const Utf8Str &aHostPath,
    57 //                  bool aWritable, const com::Utf8Str &aAutoMountPoint, bool aAutoMount, bool fFailOnError);
     61    HRESULT init(VirtualBox *aVirtualBox, const Utf8Str &aName, const Utf8Str &aHostPath,
     62                 bool aWritable, bool aAutoMount, const com::Utf8Str &aAutoMountPoint, bool fFailOnError,
     63                 SymlinkPolicy_T enmSymlinkPolicy);
     64    HRESULT init(VirtualBox *aVirtualBox, const settings::SharedFolder &rData);
    5865    void uninit();
     66    HRESULT i_saveSettings(settings::SharedFolder &data);
    5967
    6068    // public methods for internal purposes only
  • trunk/src/VBox/Main/include/VirtualBoxImpl.h

    r107239 r108046  
    171171    void i_onMediumConfigChanged(IMedium *aMedium);
    172172    void i_onMediumChanged(IMediumAttachment* aMediumAttachment);
     173    void i_onSharedFolderChanged();
    173174    void i_onStorageControllerChanged(const Guid &aMachineId, const com::Utf8Str &aControllerName);
    174175    void i_onStorageDeviceChanged(IMediumAttachment* aStorageDevice, BOOL fRemoved, BOOL fSilent);
     
    270271                                   bool aSetError,
    271272                                   ComObjPtr<Medium> &pMedium);
     273    HRESULT i_findSharedFolder(const Utf8Str &aName,
     274                               ComPtr<ISharedFolder> &aSharedFolder);
    272275
    273276    HRESULT i_findGuestOSType(const Utf8Str &strOSType,
  • trunk/src/VBox/Main/src-all/SharedFolderImpl.cpp

    r106061 r108046  
    167167}
    168168
    169 # if 0
    170169
    171170/**
    172171 *  Initializes the shared folder object.
    173172 *
    174  *  This variant initializes a global instance that lives in the server address space. It is not presently used.
     173 *  This variant initializes a global instance that lives in the server address space.
    175174 *
    176175 *  @param aVirtualBox  VirtualBox parent object
     
    178177 *  @param aHostPath    full path to the shared folder on the host
    179178 *  @param aWritable    writable if true, readonly otherwise
     179 *  @param aAutoMount   if auto mounted by guest true, false otherwise
    180180 *  @param aAutoMountPoint Where the guest should try auto mount it.
    181181 *  @param fFailOnError Whether to fail with an error if the shared folder path is bad.
     182 *  @param enmSymlinkPolicy The symbolic link creation policy to apply.
    182183 *
    183184 *  @return          COM result indicator
     
    189190                           bool aAutoMount,
    190191                           const Utf8Str &aAutoMountPoint,
    191                            bool fFailOnError)
     192                           bool fFailOnError,
     193                           SymlinkPolicy_T enmSymlinkPolicy)
    192194{
    193195    /* Enclose the state transition NotReady->InInit->Ready */
     
    197199    unconst(mVirtualBox) = aVirtualBox;
    198200
    199     HRESULT hrc = protectedInit(aVirtualBox, aName, aHostPath, aWritable, aAutoMount, aAutoMountPoint, fFailOnError);
     201    HRESULT hrc = i_protectedInit(aVirtualBox, aName, aHostPath, aWritable, aAutoMount, aAutoMountPoint, fFailOnError,
     202                                  enmSymlinkPolicy);
    200203
    201204    /* Confirm a successful initialization when it's the case */
     
    206209}
    207210
    208 # endif
     211/**
     212 *  Initializes the shared folder object.
     213 *
     214 *  This variant initializes a global instance that lives in the server address space.
     215 *
     216 *  @param aVirtualBox  VirtualBox parent object
     217 *  @param rData        Settings shared folder
     218 *
     219 *  @return          COM result indicator
     220 */
     221HRESULT SharedFolder::init(VirtualBox *aVirtualBox, const settings::SharedFolder &rData)
     222{
     223    /* Enclose the state transition NotReady->InInit->Ready */
     224    AutoInitSpan autoInitSpan(this);
     225    AssertReturn(autoInitSpan.isOk(), E_FAIL);
     226
     227    unconst(mVirtualBox) = aVirtualBox;
     228    HRESULT hrc = i_protectedInit(aVirtualBox, rData.strName, rData.strHostPath,
     229                                  rData.fWritable, rData.fAutoMount, rData.strAutoMountPoint,
     230                                  false, rData.enmSymlinkPolicy);
     231
     232    /* Confirm a successful initialization or not: */
     233    if (SUCCEEDED(hrc))
     234        autoInitSpan.setSucceeded();
     235    else
     236        autoInitSpan.setFailed(hrc);
     237    return hrc;
     238}
     239
    209240
    210241/**
     
    301332}
    302333
     334HRESULT SharedFolder::i_saveSettings(settings::SharedFolder &data)
     335{
     336    AutoCaller autoCaller(this);
     337    if (FAILED(autoCaller.hrc())) return autoCaller.hrc();
     338
     339    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
     340    AssertReturn(!m->strName.isEmpty(), E_FAIL);
     341    data.strName = m->strName;
     342    data.strHostPath = m->strHostPath;
     343    data.fWritable = m->fWritable != FALSE;
     344    data.fAutoMount = m->fAutoMount != FALSE;
     345    data.strAutoMountPoint = m->strAutoMountPoint;
     346    data.enmSymlinkPolicy = m->enmSymlinkPolicy;
     347
     348    return S_OK;
     349}
     350
    303351// wrapped ISharedFolder properties
    304352/////////////////////////////////////////////////////////////////////////////
  • trunk/src/VBox/Main/src-client/ConsoleImpl.cpp

    r107843 r108046  
    33543354            return hrc;
    33553355
    3356         /* first, remove the machine or the global folder if there is any */
     3356        /* second, add the machine or the global folder if there is any */
    33573357        SharedFolderDataMap::const_iterator it;
    33583358        if (i_findOtherSharedFolder(aName, it))
     
    94799479        if (aGlobal)
    94809480        {
    9481             /// @todo grab & process global folders when they are done
     9481            SharedFolderDataMap oldFolders;
     9482            oldFolders = m_mapGlobalSharedFolders;
     9483
     9484            m_mapGlobalSharedFolders.clear();
     9485
     9486            ComPtr<IVirtualBox> ptrVirtualBox;
     9487            hrc = mMachine->COMGETTER(Parent)(ptrVirtualBox.asOutParam());
     9488            if (FAILED(hrc)) throw hrc;
     9489            SafeIfaceArray<ISharedFolder> folders;
     9490            hrc = ptrVirtualBox->COMGETTER(SharedFolders)(ComSafeArrayAsOutParam(folders));
     9491            if (FAILED(hrc)) throw hrc;
     9492
     9493            for (size_t i = 0; i < folders.size(); ++i)
     9494            {
     9495                ComPtr<ISharedFolder> pSharedFolder = folders[i];
     9496
     9497                Bstr bstr;
     9498                hrc = pSharedFolder->COMGETTER(Name)(bstr.asOutParam());
     9499                if (FAILED(hrc)) throw hrc;
     9500                Utf8Str strName(bstr);
     9501
     9502                hrc = pSharedFolder->COMGETTER(HostPath)(bstr.asOutParam());
     9503                if (FAILED(hrc)) throw hrc;
     9504                Utf8Str strHostPath(bstr);
     9505
     9506                BOOL writable;
     9507                hrc = pSharedFolder->COMGETTER(Writable)(&writable);
     9508                if (FAILED(hrc)) throw hrc;
     9509
     9510                BOOL autoMount;
     9511                hrc = pSharedFolder->COMGETTER(AutoMount)(&autoMount);
     9512                if (FAILED(hrc)) throw hrc;
     9513
     9514                hrc = pSharedFolder->COMGETTER(AutoMountPoint)(bstr.asOutParam());
     9515                if (FAILED(hrc)) throw hrc;
     9516                Utf8Str strAutoMountPoint(bstr);
     9517
     9518                m_mapGlobalSharedFolders.insert(std::make_pair(strName,
     9519                                                               SharedFolderData(strHostPath, !!writable,
     9520                                                                                 !!autoMount, strAutoMountPoint)));
     9521
     9522                /* send changes to HGCM if the VM is running */
     9523                if (online)
     9524                {
     9525                    SharedFolderDataMap::iterator it = oldFolders.find(strName);
     9526                    if (    it == oldFolders.end()
     9527                         || it->second.m_strHostPath != strHostPath)
     9528                    {
     9529                        /* a new global folder is added or
     9530                         * the existing global folder is changed */
     9531                        if (m_mapSharedFolders.find(strName) != m_mapSharedFolders.end())
     9532                            ; /* the console folder exists, nothing to do */
     9533                        else if (m_mapMachineSharedFolders.find(strName) != m_mapMachineSharedFolders.end())
     9534                            ; /* the machine folder exists, nothing to do */
     9535                        else
     9536                        {
     9537                            /* remove the old global folder (when changed) */
     9538                            if (it != oldFolders.end())
     9539                            {
     9540                                hrc = i_removeSharedFolder(strName);
     9541                                if (FAILED(hrc)) throw hrc;
     9542                            }
     9543
     9544                            /* create the new global folder */
     9545                            hrc = i_createSharedFolder(strName,
     9546                                                       SharedFolderData(strHostPath, !!writable, !!autoMount, strAutoMountPoint));
     9547                            if (FAILED(hrc)) throw hrc;
     9548                        }
     9549                    }
     9550                    /* forget the processed (or identical) folder */
     9551                    if (it != oldFolders.end())
     9552                        oldFolders.erase(it);
     9553                }
     9554            }
     9555
     9556            /* process outdated (removed) folders */
     9557            if (online)
     9558            {
     9559                for (SharedFolderDataMap::const_iterator it = oldFolders.begin();
     9560                     it != oldFolders.end(); ++it)
     9561                {
     9562                    if (m_mapSharedFolders.find(it->first) != m_mapSharedFolders.end())
     9563                        ; /* the console folder exists, nothing to do */
     9564                    else if (m_mapMachineSharedFolders.find(it->first) != m_mapMachineSharedFolders.end())
     9565                        ; /* the machine folder exists, nothing to do */
     9566                    else
     9567                    {
     9568                        /* remove the outdated global folder */
     9569                        hrc = i_removeSharedFolder(it->first);
     9570                        if (FAILED(hrc)) throw hrc;
     9571                    }
     9572                }
     9573            }
    94829574        }
    94839575        else
     
    96179709        return true;
    96189710
    9619     /* second, search machine folders */
     9711    /* second, search global folders */
    96209712    aIt = m_mapGlobalSharedFolders.find(strName);
    96219713    if (aIt != m_mapGlobalSharedFolders.end())
  • trunk/src/VBox/Main/src-server/MachineImpl.cpp

    r107598 r108046  
    50535053    /* inform the direct session if any */
    50545054    alock.release();
    5055     i_onSharedFolderChange();
     5055    i_onSharedFolderChange(FALSE);
    50565056
    50575057    return S_OK;
     
    50755075    /* inform the direct session if any */
    50765076    alock.release();
    5077     i_onSharedFolderChange();
     5077    i_onSharedFolderChange(FALSE);
    50785078
    50795079    return S_OK;
     
    1178611786
    1178711787        if (flModifications & IsModified_SharedFolders)
    11788             that->i_onSharedFolderChange();
     11788            that->i_onSharedFolderChange(FALSE);
    1178911789
    1179011790        if (flModifications & IsModified_VRDEServer)
     
    1433114331 *  @note Locks this object for reading.
    1433214332 */
    14333 HRESULT SessionMachine::i_onSharedFolderChange()
     14333HRESULT SessionMachine::i_onSharedFolderChange(BOOL aGlobal)
    1433414334{
    1433514335    LogFlowThisFunc(("\n"));
     
    1434914349        return S_OK;
    1435014350
    14351     return directControl->OnSharedFolderChange(FALSE /* aGlobal */);
     14351    return directControl->OnSharedFolderChange(aGlobal);
    1435214352}
    1435314353
  • trunk/src/VBox/Main/src-server/VirtualBoxImpl.cpp

    r107754 r108046  
    819819        }
    820820
     821        for (settings::SharedFoldersList::const_iterator it = m->pMainConfigFile->llGlobalSharedFolders.begin();
     822             it != m->pMainConfigFile->llGlobalSharedFolders.end();
     823             ++it)
     824        {
     825            const settings::SharedFolder &sf = *it;
     826            ComObjPtr<SharedFolder> pSharedFolder;
     827            hrc = pSharedFolder.createObject();
     828            AssertComRCThrowRC(hrc);
     829            hrc = pSharedFolder->init(this, sf);
     830            if (FAILED(hrc)) throw hrc;
     831
     832            AutoWriteLock alock(m->allSharedFolders.getLockHandle() COMMA_LOCKVAL_SRC_POS);
     833            m->allSharedFolders.addChild(pSharedFolder);
     834            alock.release();
     835        }
     836
    821837        /* net services - nat networks */
    822838        for (settings::NATNetworksList::const_iterator it = m->pMainConfigFile->llNATNetworks.begin();
     
    15021518HRESULT VirtualBox::getSharedFolders(std::vector<ComPtr<ISharedFolder> > &aSharedFolders)
    15031519{
    1504     NOREF(aSharedFolders);
    1505 
    1506     return setError(E_NOTIMPL, tr("Not yet implemented"));
     1520    AutoReadLock al(m->allSharedFolders.getLockHandle() COMMA_LOCKVAL_SRC_POS);
     1521    aSharedFolders.resize(m->allSharedFolders.size());
     1522    size_t i = 0;
     1523    for (SharedFoldersOList::const_iterator it= m->allSharedFolders.begin();
     1524         it!= m->allSharedFolders.end(); ++it, ++i)
     1525         (*it).queryInterfaceTo(aSharedFolders[i].asOutParam());
     1526    return S_OK;
    15071527}
    15081528
     
    27802800                                       const com::Utf8Str &aAutoMountPoint)
    27812801{
    2782     NOREF(aName);
    2783     NOREF(aHostPath);
    2784     NOREF(aWritable);
    2785     NOREF(aAutomount);
    2786     NOREF(aAutoMountPoint);
    2787 
    2788     return setError(E_NOTIMPL, tr("Not yet implemented"));
     2802    LogFlowThisFunc(("Entering for '%s' -> '%s'\n", aName.c_str(), aHostPath.c_str()));
     2803
     2804    ComPtr<ISharedFolder> found;
     2805    HRESULT hrc = i_findSharedFolder(aName, found);
     2806    if (SUCCEEDED(hrc))
     2807        return setError(VBOX_E_OBJECT_IN_USE,
     2808                        tr("Shared folder named '%s' already exists"),
     2809                        aName.c_str());
     2810
     2811    ComObjPtr<SharedFolder> sharedFolder;
     2812    SymlinkPolicy_T enmSymlinkPolicy = SymlinkPolicy_None;
     2813    sharedFolder.createObject();
     2814    hrc = sharedFolder->init(this,
     2815                             aName,
     2816                             aHostPath,
     2817                             !!aWritable,
     2818                             !!aAutomount,
     2819                             aAutoMountPoint,
     2820                             true /* fFailOnError */,
     2821                             enmSymlinkPolicy);
     2822    if (FAILED(hrc)) return hrc;
     2823
     2824    AutoWriteLock alock(m->allSharedFolders.getLockHandle() COMMA_LOCKVAL_SRC_POS);
     2825    m->allSharedFolders.addChild(sharedFolder);
     2826    alock.release();
     2827    {
     2828        AutoWriteLock vboxLock(this COMMA_LOCKVAL_SRC_POS);
     2829        hrc = i_saveSettings();
     2830        vboxLock.release();
     2831
     2832        if (FAILED(hrc))
     2833        {
     2834            alock.acquire();
     2835            m->allSharedFolders.removeChild(sharedFolder);
     2836            alock.release();
     2837        }
     2838    }
     2839
     2840    i_onSharedFolderChanged();
     2841    LogFlowThisFunc(("Leaving for '%s' -> '%s'\n", aName.c_str(), aHostPath.c_str()));
     2842    return hrc;
    27892843}
    27902844
    27912845HRESULT VirtualBox::removeSharedFolder(const com::Utf8Str &aName)
    27922846{
    2793     NOREF(aName);
    2794     return setError(E_NOTIMPL, tr("Not yet implemented"));
     2847    LogFlowThisFunc(("Entering for '%s'\n", aName.c_str()));
     2848
     2849    ComPtr<ISharedFolder> sharedFolder;
     2850    HRESULT hrc = i_findSharedFolder(aName, sharedFolder);
     2851    if (FAILED(hrc))
     2852        return hrc;
     2853
     2854    ISharedFolder *aP = sharedFolder;
     2855    SharedFolder *aP2 = static_cast<SharedFolder *>(aP);
     2856    AutoWriteLock alock(m->allSharedFolders.getLockHandle() COMMA_LOCKVAL_SRC_POS);
     2857    m->allSharedFolders.removeChild(aP2);
     2858    alock.release();
     2859
     2860    {
     2861        AutoWriteLock vboxLock(this COMMA_LOCKVAL_SRC_POS);
     2862        hrc = i_saveSettings();
     2863        vboxLock.release();
     2864
     2865        if (FAILED(hrc))
     2866        {
     2867            alock.acquire();
     2868            m->allSharedFolders.addChild(aP2);
     2869            alock.release();
     2870        }
     2871    }
     2872
     2873    i_onSharedFolderChanged();
     2874    LogFlowThisFunc(("Leaving for '%s'\n", aName.c_str()));
     2875
     2876    return hrc;
    27952877}
    27962878
     
    36223704    AssertComRCReturnVoid(hrc);
    36233705    i_postEvent(new AsyncEvent(this, ptrEvent));
     3706}
     3707
     3708/**
     3709 *  @note Locks this object for reading.
     3710 */
     3711void VirtualBox::i_onSharedFolderChanged()
     3712{
     3713    LogFlowThisFunc(("\n"));
     3714
     3715    AutoCaller autoCaller(this);
     3716    AssertComRCReturnVoid(autoCaller.hrc());
     3717
     3718    SessionMachinesList aMachines;
     3719    i_getOpenedMachines(aMachines, NULL);
     3720    for (SessionMachinesList::iterator it = aMachines.begin();
     3721         it != aMachines.end();
     3722         ++it)
     3723    {
     3724        ComObjPtr<SessionMachine> &pMachine = *it;
     3725        AutoReadLock mlock(pMachine COMMA_LOCKVAL_SRC_POS);
     3726        pMachine->i_onSharedFolderChange(TRUE);
     3727    }
     3728    aMachines.clear();
    36243729}
    36253730
     
    45554660}
    45564661
     4662/**
     4663 *  Searches for a shared folder with the given logical name
     4664 *  in the collection of shared folders.
     4665 *
     4666 *  @param aName            logical name of the shared folder
     4667 *  @param aSharedFolder    where to return the found object
     4668 *
     4669 *  @return S_OK, E_INVALIDARG or VBOX_E_OBJECT_NOT_FOUND when not found.
     4670 *
     4671 *  @note must be called from under the object's lock
     4672 */
     4673HRESULT VirtualBox::i_findSharedFolder(const Utf8Str &aName,
     4674                                       ComPtr<ISharedFolder> &aSharedFolder)
     4675{
     4676    ComObjPtr<SharedFolder> found;
     4677
     4678    AutoReadLock alock(m->allSharedFolders.getLockHandle() COMMA_LOCKVAL_SRC_POS);
     4679
     4680    for (SharedFoldersOList::const_iterator it = m->allSharedFolders.begin();
     4681        it != m->allSharedFolders.end();
     4682        ++it)
     4683    {
     4684        Bstr bstrSharedFolderName;
     4685        HRESULT hrc = (*it)->COMGETTER(Name)(bstrSharedFolderName.asOutParam());
     4686        if (FAILED(hrc)) return hrc;
     4687
     4688        if (Utf8Str(bstrSharedFolderName) == aName)
     4689        {
     4690            found = *it;
     4691            break;
     4692        }
     4693    }
     4694    if (!found)
     4695        return VBOX_E_OBJECT_NOT_FOUND;
     4696    return found.queryInterfaceTo(aSharedFolder.asOutParam());
     4697}
     4698
    45574699/* Look for a GuestOSType object */
    45584700HRESULT VirtualBox::i_findGuestOSType(const Utf8Str &strOSType,
     
    52445386                if (FAILED(hrc)) throw hrc;
    52455387                m->pMainConfigFile->llDhcpServers.push_back(d);
     5388            }
     5389        }
     5390        m->pMainConfigFile->llGlobalSharedFolders.clear();
     5391        {
     5392            AutoReadLock sharedFolderLock(m->allSharedFolders.getLockHandle() COMMA_LOCKVAL_SRC_POS);
     5393            for (SharedFoldersOList::const_iterator it = m->allSharedFolders.begin();
     5394                 it != m->allSharedFolders.end();
     5395                 ++it)
     5396            {
     5397                settings::SharedFolder sf;
     5398                hrc = (*it)->i_saveSettings(sf);
     5399                if (FAILED(hrc)) throw hrc;
     5400                m->pMainConfigFile->llGlobalSharedFolders.push_back(sf);
    52465401            }
    52475402        }
  • trunk/src/VBox/Main/xml/Settings.cpp

    r107930 r108046  
    16481648}
    16491649
     1650/**
     1651 * Constructor. Needs to set sane defaults which stand the test of time.
     1652 */
     1653SharedFolder::SharedFolder() :
     1654    fWritable(false),
     1655    fAutoMount(false),
     1656    enmSymlinkPolicy(SymlinkPolicy_None)
     1657{
     1658}
     1659
     1660/**
     1661 * Comparison operator. This gets called from MachineConfigFile::operator==,
     1662 * which in turn gets called from Machine::saveSettings to figure out whether
     1663 * machine settings have really changed and thus need to be written out to disk.
     1664 */
     1665bool SharedFolder::operator==(const SharedFolder &g) const
     1666{
     1667    return (this == &g)
     1668        || (   strName           == g.strName
     1669            && strHostPath       == g.strHostPath
     1670            && fWritable         == g.fWritable
     1671            && fAutoMount        == g.fAutoMount
     1672            && strAutoMountPoint == g.strAutoMountPoint
     1673            && enmSymlinkPolicy  == g.enmSymlinkPolicy);
     1674}
     1675
    16501676
    16511677////////////////////////////////////////////////////////////////////////////////
     
    20982124                throw ConfigFileError(this, pelmNet, N_("Required NATNetwork/@networkName, @gateway, @network,@advertiseDefaultIpv6Route , @needDhcp or @enabled attribute is missing"));
    20992125        }
     2126    }
     2127}
     2128
     2129/**
     2130 * Reads in the \<SharedFolders\> chunk.
     2131 * @param elmSharedFolders
     2132 */
     2133void MainConfigFile::readSharedFolders(const xml::ElementNode &elmSharedFolders)
     2134{
     2135    xml::NodesLoop nl1(elmSharedFolders, "SharedFolder");
     2136    const xml::ElementNode *pelmFolder;
     2137    while ((pelmFolder = nl1.forAllNodes()))
     2138    {
     2139        SharedFolder sf;
     2140        pelmFolder->getAttributeValue("name", sf.strName);
     2141        pelmFolder->getAttributeValue("hostPath", sf.strHostPath);
     2142        pelmFolder->getAttributeValue("writable", sf.fWritable);
     2143        pelmFolder->getAttributeValue("autoMount", sf.fAutoMount);
     2144        pelmFolder->getAttributeValue("autoMountPoint", sf.strAutoMountPoint);
     2145
     2146        Utf8Str strTemp;
     2147        if (pelmFolder->getAttributeValue("symlinkPolicy", strTemp))
     2148        {
     2149            if (strTemp == "forbidden")
     2150                sf.enmSymlinkPolicy = SymlinkPolicy_Forbidden;
     2151            else if (strTemp == "subtree")
     2152                sf.enmSymlinkPolicy = SymlinkPolicy_AllowedInShareSubtree;
     2153            else if (strTemp == "relative")
     2154                sf.enmSymlinkPolicy = SymlinkPolicy_AllowedToRelativeTargets;
     2155            else if (strTemp == "any")
     2156                sf.enmSymlinkPolicy = SymlinkPolicy_AllowedToAnyTarget;
     2157            else
     2158                throw ConfigFileError(this,
     2159                                      pelmFolder,
     2160                                      N_("Invalid value '%s' in SharedFolder/@symlinkPolicy attribute"),
     2161                                      strTemp.c_str());
     2162        }
     2163        llGlobalSharedFolders.push_back(sf);
    21002164    }
    21012165}
     
    24332497                        }
    24342498                    }
     2499                    else if (pelmGlobalChild->nameEquals("SharedFolders"))
     2500                        readSharedFolders(*pelmGlobalChild);
    24352501                    else if (pelmGlobalChild->nameEquals("USBDeviceFilters"))
    24362502                        readUSBDeviceFilters(*pelmGlobalChild, host.llUSBDeviceFilters);
     
    25082574            m->sv = SettingsVersion_v1_14;
    25092575    }
     2576    if (m->sv < SettingsVersion_v1_20)
     2577    {
     2578        // VirtualBox 7.1 adds global shared folders.
     2579        if (!llGlobalSharedFolders.empty())
     2580            m->sv = SettingsVersion_v1_20;
     2581    }
     2582
    25102583}
    25112584
     
    26232696    }
    26242697#endif /* VBOX_WITH_CLOUD_NET */
     2698
     2699xml::ElementNode *pelmSharedFolders = pelmGlobal->createChild("SharedFolders");
     2700    if (!llGlobalSharedFolders.empty())
     2701    {
     2702        for (SharedFoldersList::const_iterator it = llGlobalSharedFolders.begin();
     2703             it != llGlobalSharedFolders.end();
     2704             ++it)
     2705        {
     2706            const SharedFolder &sf = *it;
     2707            xml::ElementNode *pelmThis = pelmSharedFolders->createChild("SharedFolder");
     2708            pelmThis->setAttribute("name", sf.strName);
     2709            pelmThis->setAttribute("hostPath", sf.strHostPath);
     2710            pelmThis->setAttribute("writable", sf.fWritable);
     2711            pelmThis->setAttribute("autoMount", sf.fAutoMount);
     2712            if (sf.strAutoMountPoint.isNotEmpty())
     2713                pelmThis->setAttribute("autoMountPoint", sf.strAutoMountPoint);
     2714            const char *pcszSymlinkPolicy;
     2715            if (sf.enmSymlinkPolicy != SymlinkPolicy_None)
     2716            {
     2717                switch (sf.enmSymlinkPolicy)
     2718                {
     2719                    default: /*case SymlinkPolicy_Forbidden:*/    pcszSymlinkPolicy = "forbidden";  break;
     2720                    case SymlinkPolicy_AllowedInShareSubtree:     pcszSymlinkPolicy = "subtree";    break;
     2721                    case SymlinkPolicy_AllowedToRelativeTargets:  pcszSymlinkPolicy = "relative";   break;
     2722                    case SymlinkPolicy_AllowedToAnyTarget:        pcszSymlinkPolicy = "any";        break;
     2723                }
     2724                pelmThis->setAttribute("symlinkPolicy", pcszSymlinkPolicy);
     2725            }
     2726
     2727        }
     2728    }
    26252729
    26262730#ifdef VBOX_WITH_UPDATE_AGENT
     
    37893893}
    37903894
    3791 /**
    3792  * Constructor. Needs to set sane defaults which stand the test of time.
    3793  */
    3794 SharedFolder::SharedFolder() :
    3795     fWritable(false),
    3796     fAutoMount(false),
    3797     enmSymlinkPolicy(SymlinkPolicy_None)
    3798 {
    3799 }
    3800 
    3801 /**
    3802  * Comparison operator. This gets called from MachineConfigFile::operator==,
    3803  * which in turn gets called from Machine::saveSettings to figure out whether
    3804  * machine settings have really changed and thus need to be written out to disk.
    3805  */
    3806 bool SharedFolder::operator==(const SharedFolder &g) const
    3807 {
    3808     return (this == &g)
    3809         || (   strName           == g.strName
    3810             && strHostPath       == g.strHostPath
    3811             && fWritable         == g.fWritable
    3812             && fAutoMount        == g.fAutoMount
    3813             && strAutoMountPoint == g.strAutoMountPoint
    3814             && enmSymlinkPolicy  == g.enmSymlinkPolicy);
    3815 }
    38163895
    38173896/**
  • trunk/src/VBox/Main/xml/VirtualBox-settings.xsd

    r107930 r108046  
    571571      </xsd:complexType>
    572572    </xsd:element>
     573    <xsd:element name="SharedFolders" type="TSharedFolders" minOccurs="0"/>
    573574    <xsd:element name="USBDeviceFilters">
    574575      <xsd:complexType>
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