Index: trunk/src/VBox/Frontends/VBoxManage/VBoxManageInfo.cpp
===================================================================
--- trunk/src/VBox/Frontends/VBoxManage/VBoxManageInfo.cpp	(revision 108045)
+++ trunk/src/VBox/Frontends/VBoxManage/VBoxManageInfo.cpp	(revision 108046)
@@ -2793,17 +2793,15 @@
         RTPrintf("%-28s ", Info::tr("Shared folders:"));
     uint32_t numSharedFolders = 0;
-#if 0 // not yet implemented
     /* globally shared folders first */
     {
-        SafeIfaceArray <ISharedFolder> sfColl;
-        CHECK_ERROR_RET(pVirtualBox, COMGETTER(SharedFolders)(ComSafeArrayAsOutParam(sfColl)), rc);
-        for (size_t i = 0; i < sfColl.size(); ++i)
-        {
-            ComPtr<ISharedFolder> sf = sfColl[i];
+        com::SafeIfaceArray <ISharedFolder> folders;
+        CHECK_ERROR_RET(pVirtualBox, COMGETTER(SharedFolders)(ComSafeArrayAsOutParam(folders)), hrc);
+        for (size_t i = 0; i < folders.size(); ++i)
+        {
+            ComPtr<ISharedFolder> sf = folders[i];
             showSharedFolder(sf, details, Info::tr("global mapping"), "GlobalMapping", i + 1, numSharedFolders == 0);
             ++numSharedFolders;
         }
     }
-#endif
     /* now VM mappings */
     {
Index: trunk/src/VBox/Frontends/VBoxManage/VBoxManageMisc.cpp
===================================================================
--- trunk/src/VBox/Frontends/VBoxManage/VBoxManageMisc.cpp	(revision 108045)
+++ trunk/src/VBox/Frontends/VBoxManage/VBoxManageMisc.cpp	(revision 108046)
@@ -1687,45 +1687,56 @@
      * Done parsing, do some work.
      */
-    ComPtr<IMachine> ptrMachine;
-    CHECK_ERROR2I_RET(a->virtualBox, FindMachine(Bstr(pszMachineName).raw(), ptrMachine.asOutParam()), RTEXITCODE_FAILURE);
-    AssertReturn(ptrMachine.isNotNull(), RTEXITCODE_FAILURE);
-
     HRESULT hrc;
-    if (fTransient)
-    {
-        /* open an existing session for the VM */
-        CHECK_ERROR2I_RET(ptrMachine, LockMachine(a->session, LockType_Shared), RTEXITCODE_FAILURE);
-
-        /* get the session machine */
-        ComPtr<IMachine> ptrSessionMachine;
-        CHECK_ERROR2I_RET(a->session, COMGETTER(Machine)(ptrSessionMachine.asOutParam()), RTEXITCODE_FAILURE);
-
-        /* get the session console */
-        ComPtr<IConsole> ptrConsole;
-        CHECK_ERROR2I_RET(a->session, COMGETTER(Console)(ptrConsole.asOutParam()), RTEXITCODE_FAILURE);
-        if (ptrConsole.isNull())
-            return RTMsgErrorExit(RTEXITCODE_FAILURE, Misc::tr("Machine '%s' is not currently running."), pszMachineName);
-
-        CHECK_ERROR2(hrc, ptrConsole, CreateSharedFolder(Bstr(pszName).raw(), Bstr(szAbsHostPath).raw(),
-                                                         fWritable, fAutoMount, Bstr(pszAutoMountPoint).raw()));
-        a->session->UnlockMachine();
+    if (!strcmp(pszMachineName, "global"))
+    {
+        if (fTransient)
+            return errorSyntax(Misc::tr("Invalid option: global and transient both specified"));
+        ComPtr<IVirtualBox> pVirtualBox = a->virtualBox;
+        CHECK_ERROR2(hrc, pVirtualBox, CreateSharedFolder(Bstr(pszName).raw(), Bstr(szAbsHostPath).raw(),
+                                                          fWritable, fAutoMount, Bstr(pszAutoMountPoint).raw()));
     }
     else
     {
-        /* open a session for the VM */
-        CHECK_ERROR2I_RET(ptrMachine, LockMachine(a->session, LockType_Write), RTEXITCODE_FAILURE);
-
-        /* get the mutable session machine */
-        ComPtr<IMachine> ptrSessionMachine;
-        CHECK_ERROR2I_RET(a->session, COMGETTER(Machine)(ptrSessionMachine.asOutParam()), RTEXITCODE_FAILURE);
-
-        CHECK_ERROR2(hrc, ptrSessionMachine, CreateSharedFolder(Bstr(pszName).raw(), Bstr(szAbsHostPath).raw(),
-                                                                fWritable, fAutoMount, Bstr(pszAutoMountPoint).raw()));
-        if (SUCCEEDED(hrc))
-        {
-            CHECK_ERROR2(hrc, ptrSessionMachine, SaveSettings());
-        }
-
-        a->session->UnlockMachine();
+        ComPtr<IMachine> ptrMachine;
+        CHECK_ERROR2I_RET(a->virtualBox, FindMachine(Bstr(pszMachineName).raw(), ptrMachine.asOutParam()), RTEXITCODE_FAILURE);
+        AssertReturn(ptrMachine.isNotNull(), RTEXITCODE_FAILURE);
+
+        if (fTransient)
+        {
+            /* open an existing session for the VM */
+            CHECK_ERROR2I_RET(ptrMachine, LockMachine(a->session, LockType_Shared), RTEXITCODE_FAILURE);
+
+            /* get the session machine */
+            ComPtr<IMachine> ptrSessionMachine;
+            CHECK_ERROR2I_RET(a->session, COMGETTER(Machine)(ptrSessionMachine.asOutParam()), RTEXITCODE_FAILURE);
+
+            /* get the session console */
+            ComPtr<IConsole> ptrConsole;
+            CHECK_ERROR2I_RET(a->session, COMGETTER(Console)(ptrConsole.asOutParam()), RTEXITCODE_FAILURE);
+            if (ptrConsole.isNull())
+                return RTMsgErrorExit(RTEXITCODE_FAILURE, Misc::tr("Machine '%s' is not currently running."), pszMachineName);
+
+            CHECK_ERROR2(hrc, ptrConsole, CreateSharedFolder(Bstr(pszName).raw(), Bstr(szAbsHostPath).raw(),
+                                                             fWritable, fAutoMount, Bstr(pszAutoMountPoint).raw()));
+            a->session->UnlockMachine();
+        }
+        else
+        {
+            /* open a session for the VM */
+            CHECK_ERROR2I_RET(ptrMachine, LockMachine(a->session, LockType_Write), RTEXITCODE_FAILURE);
+
+            /* get the mutable session machine */
+            ComPtr<IMachine> ptrSessionMachine;
+            CHECK_ERROR2I_RET(a->session, COMGETTER(Machine)(ptrSessionMachine.asOutParam()), RTEXITCODE_FAILURE);
+
+            CHECK_ERROR2(hrc, ptrSessionMachine, CreateSharedFolder(Bstr(pszName).raw(), Bstr(szAbsHostPath).raw(),
+                                                                    fWritable, fAutoMount, Bstr(pszAutoMountPoint).raw()));
+            if (SUCCEEDED(hrc))
+            {
+                CHECK_ERROR2(hrc, ptrSessionMachine, SaveSettings());
+            }
+
+            a->session->UnlockMachine();
+        }
     }
 
@@ -1785,43 +1796,51 @@
      * Done parsing, do some real work.
      */
-    ComPtr<IMachine> ptrMachine;
-    CHECK_ERROR2I_RET(a->virtualBox, FindMachine(Bstr(pszMachineName).raw(), ptrMachine.asOutParam()), RTEXITCODE_FAILURE);
-    AssertReturn(ptrMachine.isNotNull(), RTEXITCODE_FAILURE);
-
     HRESULT hrc;
-    if (fTransient)
-    {
-        /* open an existing session for the VM */
-        CHECK_ERROR2I_RET(ptrMachine, LockMachine(a->session, LockType_Shared), RTEXITCODE_FAILURE);
-        /* get the session machine */
-        ComPtr<IMachine> ptrSessionMachine;
-        CHECK_ERROR2I_RET(a->session, COMGETTER(Machine)(ptrSessionMachine.asOutParam()), RTEXITCODE_FAILURE);
-        /* get the session console */
-        ComPtr<IConsole> ptrConsole;
-        CHECK_ERROR2I_RET(a->session, COMGETTER(Console)(ptrConsole.asOutParam()), RTEXITCODE_FAILURE);
-        if (ptrConsole.isNull())
-            return RTMsgErrorExit(RTEXITCODE_FAILURE, Misc::tr("Machine '%s' is not currently running.\n"), pszMachineName);
-
-        CHECK_ERROR2(hrc, ptrConsole, RemoveSharedFolder(Bstr(pszName).raw()));
-
-        a->session->UnlockMachine();
+    if (!strcmp(pszMachineName, "global"))
+    {
+        ComPtr<IVirtualBox> pVirtualBox = a->virtualBox;
+        CHECK_ERROR2(hrc, pVirtualBox, RemoveSharedFolder(Bstr(pszName).raw()));
     }
     else
     {
-        /* open a session for the VM */
-        CHECK_ERROR2I_RET(ptrMachine, LockMachine(a->session, LockType_Write), RTEXITCODE_FAILURE);
-
-        /* get the mutable session machine */
-        ComPtr<IMachine> ptrSessionMachine;
-        CHECK_ERROR2I_RET(a->session, COMGETTER(Machine)(ptrSessionMachine.asOutParam()), RTEXITCODE_FAILURE);
-
-        CHECK_ERROR2(hrc, ptrSessionMachine, RemoveSharedFolder(Bstr(pszName).raw()));
-
-        /* commit and close the session */
-        if (SUCCEEDED(hrc))
-        {
-            CHECK_ERROR2(hrc, ptrSessionMachine, SaveSettings());
-        }
-        a->session->UnlockMachine();
+        ComPtr<IMachine> ptrMachine;
+        CHECK_ERROR2I_RET(a->virtualBox, FindMachine(Bstr(pszMachineName).raw(), ptrMachine.asOutParam()), RTEXITCODE_FAILURE);
+        AssertReturn(ptrMachine.isNotNull(), RTEXITCODE_FAILURE);
+
+        if (fTransient)
+        {
+            /* open an existing session for the VM */
+            CHECK_ERROR2I_RET(ptrMachine, LockMachine(a->session, LockType_Shared), RTEXITCODE_FAILURE);
+            /* get the session machine */
+            ComPtr<IMachine> ptrSessionMachine;
+            CHECK_ERROR2I_RET(a->session, COMGETTER(Machine)(ptrSessionMachine.asOutParam()), RTEXITCODE_FAILURE);
+            /* get the session console */
+            ComPtr<IConsole> ptrConsole;
+            CHECK_ERROR2I_RET(a->session, COMGETTER(Console)(ptrConsole.asOutParam()), RTEXITCODE_FAILURE);
+            if (ptrConsole.isNull())
+                return RTMsgErrorExit(RTEXITCODE_FAILURE, Misc::tr("Machine '%s' is not currently running.\n"), pszMachineName);
+
+            CHECK_ERROR2(hrc, ptrConsole, RemoveSharedFolder(Bstr(pszName).raw()));
+
+            a->session->UnlockMachine();
+        }
+        else
+        {
+            /* open a session for the VM */
+            CHECK_ERROR2I_RET(ptrMachine, LockMachine(a->session, LockType_Write), RTEXITCODE_FAILURE);
+
+            /* get the mutable session machine */
+            ComPtr<IMachine> ptrSessionMachine;
+            CHECK_ERROR2I_RET(a->session, COMGETTER(Machine)(ptrSessionMachine.asOutParam()), RTEXITCODE_FAILURE);
+
+            CHECK_ERROR2(hrc, ptrSessionMachine, RemoveSharedFolder(Bstr(pszName).raw()));
+
+            /* commit and close the session */
+            if (SUCCEEDED(hrc))
+            {
+                CHECK_ERROR2(hrc, ptrSessionMachine, SaveSettings());
+            }
+            a->session->UnlockMachine();
+        }
     }
 
Index: trunk/src/VBox/Frontends/VBoxShell/vboxshell.py
===================================================================
--- trunk/src/VBox/Frontends/VBoxShell/vboxshell.py	(revision 108045)
+++ trunk/src/VBox/Frontends/VBoxShell/vboxshell.py	(revision 108046)
@@ -1619,7 +1619,7 @@
     print("Machines: %s" % (colPath(ctx, props.defaultMachineFolder)))
 
-    #print("Global shared folders:")
-    #for ud in ctx['global'].getArray(vbox, 'sharedFolders'):
-    #    printSf(ctx, sf)
+    print("Global shared folders:")
+    for sf in ctx['global'].getArray(vbox, 'sharedFolders'):
+        printSf(ctx, sf)
     host = vbox.host
     cnt = host.processorCount
@@ -2648,7 +2648,8 @@
         return 0
 
-    mach = argsToMach(ctx, args)
-    if mach is None:
-        return 0
+    if args[1] != 'global':
+        mach = argsToMach(ctx, args)
+        if mach is None:
+            return 0
     path = args[2]
     name = args[3]
@@ -2661,5 +2662,7 @@
             if cur_arg == 'persistent':
                 persistent = True
-    if persistent:
+    if args[1] == 'global':
+        ctx['vb'].createSharedFolder(name, path, writable)
+    elif persistent:
         cmdClosedVm(ctx, mach, lambda ctx, mach, args: mach.createSharedFolder(name, path, writable), [])
     else:
@@ -2672,16 +2675,24 @@
         return 0
 
-    mach = argsToMach(ctx, args)
-    if mach is None:
-        return 0
+    if args[1] != 'global':
+        mach = argsToMach(ctx, args)
+        if mach is None:
+            return 0
     name = args[2]
     found = False
-    for sharedfolder in ctx['global'].getArray(mach, 'sharedFolders'):
-        if sharedfolder.name == name:
-            cmdClosedVm(ctx, mach, lambda ctx, mach, args: mach.removeSharedFolder(name), [])
-            found = True
-            break
-    if not found:
-        cmdExistingVm(ctx, mach, 'guestlambda', [lambda ctx, mach, console, args: console.removeSharedFolder(name)])
+    if args[1] == 'global':
+        for sharedfolder in ctx['global'].getArray(ctx['vb'], 'sharedFolders'):
+            if sharedfolder.name == name:
+                ctx['vb'].removeSharedFolder(name)
+                found = True
+                break
+    else:
+        for sharedfolder in ctx['global'].getArray(mach, 'sharedFolders'):
+            if sharedfolder.name == name:
+                cmdClosedVm(ctx, mach, lambda ctx, mach, args: mach.removeSharedFolder(name), [])
+                found = True
+                break
+        if not found:
+            cmdExistingVm(ctx, mach, 'guestlambda', [lambda ctx, mach, console, args: console.removeSharedFolder(name)])
     return 0
 
Index: trunk/src/VBox/Frontends/VirtualBox/src/extradata/UIExtraDataDefs.h
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/src/extradata/UIExtraDataDefs.h	(revision 108045)
+++ trunk/src/VBox/Frontends/VirtualBox/src/extradata/UIExtraDataDefs.h	(revision 108046)
@@ -896,4 +896,5 @@
 enum UISharedFolderType
 {
+    UISharedFolderType_Global,
     UISharedFolderType_Machine,
     UISharedFolderType_Console
Index: trunk/src/VBox/Frontends/VirtualBox/src/globals/UIDetailsGenerator.cpp
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/src/globals/UIDetailsGenerator.cpp	(revision 108045)
+++ trunk/src/VBox/Frontends/VirtualBox/src/globals/UIDetailsGenerator.cpp	(revision 108046)
@@ -1411,4 +1411,6 @@
     /* Enumerate all the folders: */
     QMap<QString, QString> folders;
+    foreach (const CSharedFolder &comGlobalFolder, gpGlobalSession->virtualBox().GetSharedFolders())
+        folders.insert(comGlobalFolder.GetName(), comGlobalFolder.GetHostPath());
     foreach (const CSharedFolder &comPermanentFolder, comMachine.GetSharedFolders())
         folders.insert(comPermanentFolder.GetName(), comPermanentFolder.GetHostPath());
Index: trunk/src/VBox/Frontends/VirtualBox/src/settings/editors/UISharedFolderDetailsEditor.cpp
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/src/settings/editors/UISharedFolderDetailsEditor.cpp	(revision 108045)
+++ trunk/src/VBox/Frontends/VirtualBox/src/settings/editors/UISharedFolderDetailsEditor.cpp	(revision 108046)
@@ -57,4 +57,5 @@
     , m_pCheckBoxAutoMount(0)
     , m_pCheckBoxPermanent(0)
+    , m_pCheckBoxGlobal(0)
     , m_pButtonBox(0)
 {
@@ -115,4 +116,15 @@
 {
     return m_pEditorAutoMountPoint ? m_pEditorAutoMountPoint->text() : QString();
+}
+
+void UISharedFolderDetailsEditor::setGlobal(bool fGlobal)
+{
+    if (m_pCheckBoxGlobal)
+        m_pCheckBoxGlobal->setChecked(fGlobal);
+}
+
+bool UISharedFolderDetailsEditor::isGlobal() const
+{
+    return m_pCheckBoxGlobal ? m_pCheckBoxGlobal->isChecked() : false;
 }
 
@@ -171,7 +183,19 @@
     if (m_pCheckBoxPermanent)
     {
-        m_pCheckBoxPermanent->setText(tr("&Make Permanent"));
-        m_pCheckBoxPermanent->setToolTip(tr("When checked, this shared folder will be permanent."));
-    }
+        m_pCheckBoxPermanent->setText(tr("&Make Machine-permanent"));
+        m_pCheckBoxPermanent->setToolTip(tr("When checked, this shared folder will be permanent "
+                                            "to this guest machine."));
+    }
+    if (m_pCheckBoxGlobal)
+    {
+        m_pCheckBoxGlobal->setText(tr("&Make Global"));
+        m_pCheckBoxGlobal->setToolTip(tr("When checked, this shared folder will be available "
+                                         "to all VMs."));
+    }
+}
+
+void UISharedFolderDetailsEditor::sltGlobalToggled()
+{
+    m_pCheckBoxPermanent->setHidden(m_pCheckBoxGlobal->isChecked());
 }
 
@@ -253,5 +277,5 @@
     if (pLayout)
     {
-        pLayout->setRowStretch(6, 1);
+        pLayout->setRowStretch(7, 1);
 
         /* Prepare path label: */
@@ -311,4 +335,10 @@
             pLayout->addWidget(m_pCheckBoxPermanent, 5, 1);
         }
+        /* Prepare global check-box: */
+        m_pCheckBoxGlobal = new QCheckBox(this);
+        if (m_pCheckBoxGlobal)
+        {
+            pLayout->addWidget(m_pCheckBoxGlobal, 6, 1);
+        }
 
         /* Prepare button-box: */
@@ -317,5 +347,5 @@
         {
             m_pButtonBox->setStandardButtons(QDialogButtonBox::Cancel | QDialogButtonBox::Ok);
-            pLayout->addWidget(m_pButtonBox, 7, 0, 1, 2);
+            pLayout->addWidget(m_pButtonBox, 8, 0, 1, 2);
         }
     }
@@ -335,6 +365,10 @@
                 this, &UISharedFolderDetailsEditor::sltValidate);
     if (m_fUsePermanent)
+    {
         connect(m_pCheckBoxPermanent, &QCheckBox::toggled,
                 this, &UISharedFolderDetailsEditor::sltValidate);
+        connect(m_pCheckBoxGlobal, &QCheckBox::toggled,
+                this, &UISharedFolderDetailsEditor::sltGlobalToggled);
+    }
     if (m_pButtonBox)
     {
Index: trunk/src/VBox/Frontends/VirtualBox/src/settings/editors/UISharedFolderDetailsEditor.h
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/src/settings/editors/UISharedFolderDetailsEditor.h	(revision 108045)
+++ trunk/src/VBox/Frontends/VirtualBox/src/settings/editors/UISharedFolderDetailsEditor.h	(revision 108046)
@@ -95,8 +95,15 @@
     bool isPermanent() const;
 
+    /** Defines whether folder is @a fGlobal. */
+    void setGlobal(bool fGlobal);
+    /** Returns whether folder is global. */
+    bool isGlobal() const;
+
 private slots:
 
     /** Handles translation event. */
     void sltRetranslateUI();
+    /** Handles global/machine folder button visibility. */
+    void sltGlobalToggled();
     /** Holds signal about folder path selected. */
     void sltSelectPath();
@@ -143,4 +150,6 @@
         /** Holds the permanent check-box instance. */
         QCheckBox          *m_pCheckBoxPermanent;
+        /** Holds the global check-box instance. */
+        QCheckBox          *m_pCheckBoxGlobal;
         /** Holds the button-box instance. */
         QIDialogButtonBox  *m_pButtonBox;
Index: trunk/src/VBox/Frontends/VirtualBox/src/settings/editors/UISharedFoldersEditor.cpp
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/src/settings/editors/UISharedFoldersEditor.cpp	(revision 108045)
+++ trunk/src/VBox/Frontends/VirtualBox/src/settings/editors/UISharedFoldersEditor.cpp	(revision 108046)
@@ -466,6 +466,8 @@
     const bool fAddEnabled = pCurrentItem;
     const bool fRemoveEnabled = fAddEnabled && pCurrentItem->parent();
+    SFTreeViewItem *pItem = static_cast<SFTreeViewItem*>(pCurrentItem);
+    const bool fEditEnabled = fRemoveEnabled && pItem->m_enmType != UISharedFolderType_Global;
     m_pActionAdd->setEnabled(fAddEnabled);
-    m_pActionEdit->setEnabled(fRemoveEnabled);
+    m_pActionEdit->setEnabled(fEditEnabled);
     m_pActionRemove->setEnabled(fRemoveEnabled);
 }
@@ -473,5 +475,8 @@
 void UISharedFoldersEditor::sltHandleDoubleClick(QTreeWidgetItem *pItem)
 {
-    const bool fEditEnabled = pItem && pItem->parent();
+    SFTreeViewItem *pSFItem = static_cast<SFTreeViewItem*>(pItem);
+    const bool fEditEnabled =    pItem
+                              && pItem->parent()
+                              && pSFItem->m_enmType != UISharedFolderType_Global;
     if (fEditEnabled)
         sltEditFolder();
@@ -484,5 +489,7 @@
     if (m_pTreeWidget->isEnabled() && pItem && pItem->flags() & Qt::ItemIsSelectable)
     {
-        menu.addAction(m_pActionEdit);
+        SFTreeViewItem *pSFItem = static_cast<SFTreeViewItem*>(pItem);
+        if (pSFItem->m_enmType != UISharedFolderType_Global)
+            menu.addAction(m_pActionEdit);
         menu.addAction(m_pActionRemove);
     }
@@ -508,5 +515,9 @@
         const QString strName = dlgFolderDetails.name();
         const QString strPath = dlgFolderDetails.path();
-        const UISharedFolderType enmType = dlgFolderDetails.isPermanent() ? UISharedFolderType_Machine : UISharedFolderType_Console;
+        const UISharedFolderType enmType =   dlgFolderDetails.isGlobal()
+                                           ? UISharedFolderType_Global
+                                           : dlgFolderDetails.isPermanent()
+                                           ? UISharedFolderType_Machine
+                                           : UISharedFolderType_Console;
         /* Shared folder's name & path could not be empty: */
         Assert(!strName.isEmpty() && !strPath.isEmpty());
@@ -546,4 +557,5 @@
     dlgFolderDetails.setName(pItem->m_strName);
     dlgFolderDetails.setPermanent(pItem->m_enmType == UISharedFolderType_Machine);
+    dlgFolderDetails.setGlobal(pItem->m_enmType == UISharedFolderType_Global);
     dlgFolderDetails.setWriteable(pItem->m_fWritable);
     dlgFolderDetails.setAutoMount(pItem->m_fAutoMount);
@@ -555,5 +567,9 @@
         const QString strName = dlgFolderDetails.name();
         const QString strPath = dlgFolderDetails.path();
-        const UISharedFolderType enmType = dlgFolderDetails.isPermanent() ? UISharedFolderType_Machine : UISharedFolderType_Console;
+        const UISharedFolderType enmType =   dlgFolderDetails.isGlobal()
+                                           ? UISharedFolderType_Global
+                                           : dlgFolderDetails.isPermanent()
+                                           ? UISharedFolderType_Machine
+                                           : UISharedFolderType_Console;
         /* Shared folder's name & path could not be empty: */
         Assert(!strName.isEmpty() && !strPath.isEmpty());
@@ -751,4 +767,5 @@
             switch (enmSharedFolderType)
             {
+                case UISharedFolderType_Global: pRootItem->m_strName = tr(" Global Folders"); break;
                 case UISharedFolderType_Machine: pRootItem->m_strName = tr(" Machine Folders"); break;
                 case UISharedFolderType_Console: pRootItem->m_strName = tr(" Transient Folders"); break;
@@ -766,4 +783,6 @@
 void UISharedFoldersEditor::updateRootItemsVisibility()
 {
+    /* Update (show/hide) global root item: */
+    setRootItemVisible(UISharedFolderType_Global, m_foldersAvailable.value(UISharedFolderType_Global));
     /* Update (show/hide) machine (permanent) root item: */
     setRootItemVisible(UISharedFolderType_Machine, m_foldersAvailable.value(UISharedFolderType_Machine));
Index: trunk/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsSF.cpp
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsSF.cpp	(revision 108045)
+++ trunk/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsSF.cpp	(revision 108046)
@@ -31,4 +31,5 @@
 /* GUI includes: */
 #include "UIErrorString.h"
+#include "UIGlobalSession.h"
 #include "UIMachineSettingsSF.h"
 #include "UISharedFoldersEditor.h"
@@ -106,4 +107,10 @@
     /* Get actual folders: */
     QMultiMap<UISharedFolderType, CSharedFolder> folders;
+    /* Load global folders: */
+    if (isSharedFolderTypeSupported(UISharedFolderType_Global))
+    {
+        foreach (const CSharedFolder &folder, getSharedFolders(UISharedFolderType_Global))
+            folders.insert(UISharedFolderType_Global, folder);
+    }
     /* Load machine (permanent) folders if allowed: */
     if (isSharedFolderTypeSupported(UISharedFolderType_Machine))
@@ -215,4 +222,5 @@
     /* Polish availability: */
     m_pEditorSharedFolders->setFeatureAvailable(isMachineInValidMode());
+    m_pEditorSharedFolders->setFoldersAvailable(UISharedFolderType_Global, isSharedFolderTypeSupported(UISharedFolderType_Global));
     m_pEditorSharedFolders->setFoldersAvailable(UISharedFolderType_Machine, isSharedFolderTypeSupported(UISharedFolderType_Machine));
     m_pEditorSharedFolders->setFoldersAvailable(UISharedFolderType_Console, isSharedFolderTypeSupported(UISharedFolderType_Console));
@@ -264,4 +272,5 @@
     switch (enmSharedFolderType)
     {
+        case UISharedFolderType_Global: return true;
         case UISharedFolderType_Machine: return isMachineInValidMode();
         case UISharedFolderType_Console: return isMachineOnline();
@@ -289,4 +298,17 @@
         switch (enmFoldersType)
         {
+            case UISharedFolderType_Global:
+            {
+                /* Load global folders: */
+                CVirtualBox vbox = gpGlobalSession->virtualBox();
+                folders = vbox.GetSharedFolders();
+                fSuccess = vbox.isOk();
+
+                /* Show error message if necessary: */
+                if (!fSuccess)
+                    notifyOperationProgressError(UIErrorString::formatErrorInfo(vbox));
+
+                break;
+            }
             case UISharedFolderType_Machine:
             {
@@ -413,4 +435,17 @@
             switch (enmFoldersType)
             {
+                case UISharedFolderType_Global:
+                {
+                    /* Remove existing folder: */
+                    CVirtualBox vbox = gpGlobalSession->virtualBox();
+                    vbox.RemoveSharedFolder(strFolderName);
+                    fSuccess = vbox.isOk();
+                    if (!fSuccess)
+                    {
+                        /* Show error message: */
+                        notifyOperationProgressError(UIErrorString::formatErrorInfo(vbox));
+                    }
+                    break;
+                }
                 case UISharedFolderType_Machine:
                 {
@@ -474,4 +509,15 @@
         switch (enmFoldersType)
         {
+            case UISharedFolderType_Global:
+            {
+                /* Create new folder: */
+                CVirtualBox vbox = gpGlobalSession->virtualBox();
+                vbox.CreateSharedFolder(strFolderName, strFolderPath, fIsWritable, fIsAutoMount, strAutoMountPoint);
+                /* Show error if the operation failed: */
+                fSuccess = vbox.isOk();
+                if (!fSuccess)
+                    notifyOperationProgressError(UIErrorString::formatErrorInfo(vbox));
+                break;
+            }
             case UISharedFolderType_Machine:
             {
Index: trunk/src/VBox/Main/idl/VirtualBox.xidl
===================================================================
--- trunk/src/VBox/Main/idl/VirtualBox.xidl	(revision 108045)
+++ trunk/src/VBox/Main/idl/VirtualBox.xidl	(revision 108046)
@@ -2764,5 +2764,5 @@
   <interface
     name="IVirtualBox" extends="$unknown"
-    uuid="d644ad1e-c501-4fc7-9ab6-aa6d763bc540"
+    uuid="2ce10519-3c09-45d8-a12d-e887786146b7"
     wsmap="managed"
     rest="managed"
@@ -2952,9 +2952,4 @@
         <link to="#createSharedFolder"/>. Existing shared folders can be
         removed using <link to="#removeSharedFolder"/>.
-
-        <note>
-          In the current version of the product, global shared folders are not
-          implemented and therefore this collection is always empty.
-        </note>
       </desc>
     </attribute>
@@ -3630,8 +3625,12 @@
         folders and starts sharing it. Refer to the description of
         <link to="ISharedFolder"/> to read more about logical names.
-        <note>
-          In the current implementation, this operation is not
-          implemented.
-        </note>
+
+        <result name="VBOX_E_OBJECT_IN_USE">
+          Shared folder already exists.
+        </result>
+        <result name="VBOX_E_FILE_ERROR">
+          Shared folder @a hostPath not accessible.
+        </result>
+
       </desc>
       <param name="name" type="wstring" dir="in">
@@ -3662,8 +3661,9 @@
         created by <link to="#createSharedFolder"/> from the collection of
         shared folders and stops sharing it.
-        <note>
-          In the current implementation, this operation is not
-          implemented.
-        </note>
+
+        <result name="VBOX_E_OBJECT_NOT_FOUND">
+          Shared folder @a name does not exist.
+        </result>
+
       </desc>
       <param name="name" type="wstring" dir="in">
@@ -24717,9 +24717,4 @@
       are in different name spaces, so they don't overlap and don't need to
       have unique logical names.
-
-      <note>
-        Global shared folders are not implemented in the current version of the
-        product.
-      </note>
     </desc>
 
Index: trunk/src/VBox/Main/include/ConsoleSharedFolderImpl.h
===================================================================
--- trunk/src/VBox/Main/include/ConsoleSharedFolderImpl.h	(revision 108045)
+++ trunk/src/VBox/Main/include/ConsoleSharedFolderImpl.h	(revision 108046)
@@ -53,6 +53,6 @@
     HRESULT init(Console *aConsole, const com::Utf8Str &aName, const com::Utf8Str &aHostPath,
                  bool aWritable, bool aAutoMount, const com::Utf8Str &aAutoMountPoint, bool fFailOnError);
-//     HRESULT init(VirtualBox *aVirtualBox, const Utf8Str &aName, const Utf8Str &aHostPath,
-//                  bool aWritable, const com::Utf8Str &aAutoMountPoint, bool aAutoMount, bool fFailOnError);
+//  HRESULT init(VirtualBox *aVirtualBox, const Utf8Str &aName, const Utf8Str &aHostPath,
+//               bool aWritable, bool aAutoMount, const com::Utf8Str &aAutoMountPoint, bool fFailOnError);
     void uninit();
 
Index: trunk/src/VBox/Main/include/MachineImpl.h
===================================================================
--- trunk/src/VBox/Main/include/MachineImpl.h	(revision 108045)
+++ trunk/src/VBox/Main/include/MachineImpl.h	(revision 108046)
@@ -566,5 +566,5 @@
     virtual HRESULT i_onCPUExecutionCapChange(ULONG /* aExecutionCap */) { return S_OK; }
     virtual HRESULT i_onMediumChange(IMediumAttachment * /* mediumAttachment */, BOOL /* force */) { return S_OK; }
-    virtual HRESULT i_onSharedFolderChange() { return S_OK; }
+    virtual HRESULT i_onSharedFolderChange(BOOL /* aGlobal */) { return S_OK; }
     virtual HRESULT i_onVMProcessPriorityChange(VMProcPriority_T /* aPriority */) { return S_OK; }
     virtual HRESULT i_onClipboardModeChange(ClipboardMode_T /* aClipboardMode */) { return S_OK; }
@@ -1408,5 +1408,5 @@
     HRESULT i_onUSBDeviceDetach(IN_BSTR aId,
                                 IVirtualBoxErrorInfo *aError);
-    HRESULT i_onSharedFolderChange() RT_OVERRIDE;
+    HRESULT i_onSharedFolderChange(BOOL aGlobal) RT_OVERRIDE;
     HRESULT i_onClipboardModeChange(ClipboardMode_T aClipboardMode) RT_OVERRIDE;
     HRESULT i_onClipboardFileTransferModeChange(BOOL aEnable) RT_OVERRIDE;
Index: trunk/src/VBox/Main/include/SharedFolderImpl.h
===================================================================
--- trunk/src/VBox/Main/include/SharedFolderImpl.h	(revision 108045)
+++ trunk/src/VBox/Main/include/SharedFolderImpl.h	(revision 108046)
@@ -37,4 +37,9 @@
 class Console;
 
+namespace settings
+{
+    struct SharedFolder;
+}
+
 class ATL_NO_VTABLE SharedFolder :
     public SharedFolderWrap
@@ -54,7 +59,10 @@
 //    HRESULT init(Console *aConsole, const com::Utf8Str &aName, const com::Utf8Str &aHostPath,
 //                 bool aWritable, bool aAutoMount, const com::Utf8Str &aAutoMountPoint, bool fFailOnError);
-//     HRESULT init(VirtualBox *aVirtualBox, const Utf8Str &aName, const Utf8Str &aHostPath,
-//                  bool aWritable, const com::Utf8Str &aAutoMountPoint, bool aAutoMount, bool fFailOnError);
+    HRESULT init(VirtualBox *aVirtualBox, const Utf8Str &aName, const Utf8Str &aHostPath,
+                 bool aWritable, bool aAutoMount, const com::Utf8Str &aAutoMountPoint, bool fFailOnError,
+                 SymlinkPolicy_T enmSymlinkPolicy);
+    HRESULT init(VirtualBox *aVirtualBox, const settings::SharedFolder &rData);
     void uninit();
+    HRESULT i_saveSettings(settings::SharedFolder &data);
 
     // public methods for internal purposes only
Index: trunk/src/VBox/Main/include/VirtualBoxImpl.h
===================================================================
--- trunk/src/VBox/Main/include/VirtualBoxImpl.h	(revision 108045)
+++ trunk/src/VBox/Main/include/VirtualBoxImpl.h	(revision 108046)
@@ -171,4 +171,5 @@
     void i_onMediumConfigChanged(IMedium *aMedium);
     void i_onMediumChanged(IMediumAttachment* aMediumAttachment);
+    void i_onSharedFolderChanged();
     void i_onStorageControllerChanged(const Guid &aMachineId, const com::Utf8Str &aControllerName);
     void i_onStorageDeviceChanged(IMediumAttachment* aStorageDevice, BOOL fRemoved, BOOL fSilent);
@@ -270,4 +271,6 @@
                                    bool aSetError,
                                    ComObjPtr<Medium> &pMedium);
+    HRESULT i_findSharedFolder(const Utf8Str &aName,
+                               ComPtr<ISharedFolder> &aSharedFolder);
 
     HRESULT i_findGuestOSType(const Utf8Str &strOSType,
Index: trunk/src/VBox/Main/src-all/SharedFolderImpl.cpp
===================================================================
--- trunk/src/VBox/Main/src-all/SharedFolderImpl.cpp	(revision 108045)
+++ trunk/src/VBox/Main/src-all/SharedFolderImpl.cpp	(revision 108046)
@@ -167,10 +167,9 @@
 }
 
-# if 0
 
 /**
  *  Initializes the shared folder object.
  *
- *  This variant initializes a global instance that lives in the server address space. It is not presently used.
+ *  This variant initializes a global instance that lives in the server address space.
  *
  *  @param aVirtualBox  VirtualBox parent object
@@ -178,6 +177,8 @@
  *  @param aHostPath    full path to the shared folder on the host
  *  @param aWritable    writable if true, readonly otherwise
+ *  @param aAutoMount   if auto mounted by guest true, false otherwise
  *  @param aAutoMountPoint Where the guest should try auto mount it.
  *  @param fFailOnError Whether to fail with an error if the shared folder path is bad.
+ *  @param enmSymlinkPolicy The symbolic link creation policy to apply.
  *
  *  @return          COM result indicator
@@ -189,5 +190,6 @@
                            bool aAutoMount,
                            const Utf8Str &aAutoMountPoint,
-                           bool fFailOnError)
+                           bool fFailOnError,
+                           SymlinkPolicy_T enmSymlinkPolicy)
 {
     /* Enclose the state transition NotReady->InInit->Ready */
@@ -197,5 +199,6 @@
     unconst(mVirtualBox) = aVirtualBox;
 
-    HRESULT hrc = protectedInit(aVirtualBox, aName, aHostPath, aWritable, aAutoMount, aAutoMountPoint, fFailOnError);
+    HRESULT hrc = i_protectedInit(aVirtualBox, aName, aHostPath, aWritable, aAutoMount, aAutoMountPoint, fFailOnError,
+                                  enmSymlinkPolicy);
 
     /* Confirm a successful initialization when it's the case */
@@ -206,5 +209,33 @@
 }
 
-# endif
+/**
+ *  Initializes the shared folder object.
+ *
+ *  This variant initializes a global instance that lives in the server address space.
+ *
+ *  @param aVirtualBox  VirtualBox parent object
+ *  @param rData        Settings shared folder
+ *
+ *  @return          COM result indicator
+ */
+HRESULT SharedFolder::init(VirtualBox *aVirtualBox, const settings::SharedFolder &rData)
+{
+    /* Enclose the state transition NotReady->InInit->Ready */
+    AutoInitSpan autoInitSpan(this);
+    AssertReturn(autoInitSpan.isOk(), E_FAIL);
+
+    unconst(mVirtualBox) = aVirtualBox;
+    HRESULT hrc = i_protectedInit(aVirtualBox, rData.strName, rData.strHostPath,
+                                  rData.fWritable, rData.fAutoMount, rData.strAutoMountPoint,
+                                  false, rData.enmSymlinkPolicy);
+
+    /* Confirm a successful initialization or not: */
+    if (SUCCEEDED(hrc))
+        autoInitSpan.setSucceeded();
+    else
+        autoInitSpan.setFailed(hrc);
+    return hrc;
+}
+
 
 /**
@@ -301,4 +332,21 @@
 }
 
+HRESULT SharedFolder::i_saveSettings(settings::SharedFolder &data)
+{
+    AutoCaller autoCaller(this);
+    if (FAILED(autoCaller.hrc())) return autoCaller.hrc();
+
+    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
+    AssertReturn(!m->strName.isEmpty(), E_FAIL);
+    data.strName = m->strName;
+    data.strHostPath = m->strHostPath;
+    data.fWritable = m->fWritable != FALSE;
+    data.fAutoMount = m->fAutoMount != FALSE;
+    data.strAutoMountPoint = m->strAutoMountPoint;
+    data.enmSymlinkPolicy = m->enmSymlinkPolicy;
+
+    return S_OK;
+}
+
 // wrapped ISharedFolder properties
 /////////////////////////////////////////////////////////////////////////////
Index: trunk/src/VBox/Main/src-client/ConsoleImpl.cpp
===================================================================
--- trunk/src/VBox/Main/src-client/ConsoleImpl.cpp	(revision 108045)
+++ trunk/src/VBox/Main/src-client/ConsoleImpl.cpp	(revision 108046)
@@ -3354,5 +3354,5 @@
             return hrc;
 
-        /* first, remove the machine or the global folder if there is any */
+        /* second, add the machine or the global folder if there is any */
         SharedFolderDataMap::const_iterator it;
         if (i_findOtherSharedFolder(aName, it))
@@ -9479,5 +9479,97 @@
         if (aGlobal)
         {
-            /// @todo grab & process global folders when they are done
+            SharedFolderDataMap oldFolders;
+            oldFolders = m_mapGlobalSharedFolders;
+
+            m_mapGlobalSharedFolders.clear();
+
+            ComPtr<IVirtualBox> ptrVirtualBox;
+            hrc = mMachine->COMGETTER(Parent)(ptrVirtualBox.asOutParam());
+            if (FAILED(hrc)) throw hrc;
+            SafeIfaceArray<ISharedFolder> folders;
+            hrc = ptrVirtualBox->COMGETTER(SharedFolders)(ComSafeArrayAsOutParam(folders));
+            if (FAILED(hrc)) throw hrc;
+
+            for (size_t i = 0; i < folders.size(); ++i)
+            {
+                ComPtr<ISharedFolder> pSharedFolder = folders[i];
+
+                Bstr bstr;
+                hrc = pSharedFolder->COMGETTER(Name)(bstr.asOutParam());
+                if (FAILED(hrc)) throw hrc;
+                Utf8Str strName(bstr);
+
+                hrc = pSharedFolder->COMGETTER(HostPath)(bstr.asOutParam());
+                if (FAILED(hrc)) throw hrc;
+                Utf8Str strHostPath(bstr);
+
+                BOOL writable;
+                hrc = pSharedFolder->COMGETTER(Writable)(&writable);
+                if (FAILED(hrc)) throw hrc;
+
+                BOOL autoMount;
+                hrc = pSharedFolder->COMGETTER(AutoMount)(&autoMount);
+                if (FAILED(hrc)) throw hrc;
+
+                hrc = pSharedFolder->COMGETTER(AutoMountPoint)(bstr.asOutParam());
+                if (FAILED(hrc)) throw hrc;
+                Utf8Str strAutoMountPoint(bstr);
+
+                m_mapGlobalSharedFolders.insert(std::make_pair(strName,
+                                                               SharedFolderData(strHostPath, !!writable,
+                                                                                 !!autoMount, strAutoMountPoint)));
+
+                /* send changes to HGCM if the VM is running */
+                if (online)
+                {
+                    SharedFolderDataMap::iterator it = oldFolders.find(strName);
+                    if (    it == oldFolders.end()
+                         || it->second.m_strHostPath != strHostPath)
+                    {
+                        /* a new global folder is added or
+                         * the existing global folder is changed */
+                        if (m_mapSharedFolders.find(strName) != m_mapSharedFolders.end())
+                            ; /* the console folder exists, nothing to do */
+                        else if (m_mapMachineSharedFolders.find(strName) != m_mapMachineSharedFolders.end())
+                            ; /* the machine folder exists, nothing to do */
+                        else
+                        {
+                            /* remove the old global folder (when changed) */
+                            if (it != oldFolders.end())
+                            {
+                                hrc = i_removeSharedFolder(strName);
+                                if (FAILED(hrc)) throw hrc;
+                            }
+
+                            /* create the new global folder */
+                            hrc = i_createSharedFolder(strName,
+                                                       SharedFolderData(strHostPath, !!writable, !!autoMount, strAutoMountPoint));
+                            if (FAILED(hrc)) throw hrc;
+                        }
+                    }
+                    /* forget the processed (or identical) folder */
+                    if (it != oldFolders.end())
+                        oldFolders.erase(it);
+                }
+            }
+
+            /* process outdated (removed) folders */
+            if (online)
+            {
+                for (SharedFolderDataMap::const_iterator it = oldFolders.begin();
+                     it != oldFolders.end(); ++it)
+                {
+                    if (m_mapSharedFolders.find(it->first) != m_mapSharedFolders.end())
+                        ; /* the console folder exists, nothing to do */
+                    else if (m_mapMachineSharedFolders.find(it->first) != m_mapMachineSharedFolders.end())
+                        ; /* the machine folder exists, nothing to do */
+                    else
+                    {
+                        /* remove the outdated global folder */
+                        hrc = i_removeSharedFolder(it->first);
+                        if (FAILED(hrc)) throw hrc;
+                    }
+                }
+            }
         }
         else
@@ -9617,5 +9709,5 @@
         return true;
 
-    /* second, search machine folders */
+    /* second, search global folders */
     aIt = m_mapGlobalSharedFolders.find(strName);
     if (aIt != m_mapGlobalSharedFolders.end())
Index: trunk/src/VBox/Main/src-server/MachineImpl.cpp
===================================================================
--- trunk/src/VBox/Main/src-server/MachineImpl.cpp	(revision 108045)
+++ trunk/src/VBox/Main/src-server/MachineImpl.cpp	(revision 108046)
@@ -5053,5 +5053,5 @@
     /* inform the direct session if any */
     alock.release();
-    i_onSharedFolderChange();
+    i_onSharedFolderChange(FALSE);
 
     return S_OK;
@@ -5075,5 +5075,5 @@
     /* inform the direct session if any */
     alock.release();
-    i_onSharedFolderChange();
+    i_onSharedFolderChange(FALSE);
 
     return S_OK;
@@ -11786,5 +11786,5 @@
 
         if (flModifications & IsModified_SharedFolders)
-            that->i_onSharedFolderChange();
+            that->i_onSharedFolderChange(FALSE);
 
         if (flModifications & IsModified_VRDEServer)
@@ -14331,5 +14331,5 @@
  *  @note Locks this object for reading.
  */
-HRESULT SessionMachine::i_onSharedFolderChange()
+HRESULT SessionMachine::i_onSharedFolderChange(BOOL aGlobal)
 {
     LogFlowThisFunc(("\n"));
@@ -14349,5 +14349,5 @@
         return S_OK;
 
-    return directControl->OnSharedFolderChange(FALSE /* aGlobal */);
+    return directControl->OnSharedFolderChange(aGlobal);
 }
 
Index: trunk/src/VBox/Main/src-server/VirtualBoxImpl.cpp
===================================================================
--- trunk/src/VBox/Main/src-server/VirtualBoxImpl.cpp	(revision 108045)
+++ trunk/src/VBox/Main/src-server/VirtualBoxImpl.cpp	(revision 108046)
@@ -819,4 +819,20 @@
         }
 
+        for (settings::SharedFoldersList::const_iterator it = m->pMainConfigFile->llGlobalSharedFolders.begin();
+             it != m->pMainConfigFile->llGlobalSharedFolders.end();
+             ++it)
+        {
+            const settings::SharedFolder &sf = *it;
+            ComObjPtr<SharedFolder> pSharedFolder;
+            hrc = pSharedFolder.createObject();
+            AssertComRCThrowRC(hrc);
+            hrc = pSharedFolder->init(this, sf);
+            if (FAILED(hrc)) throw hrc;
+
+            AutoWriteLock alock(m->allSharedFolders.getLockHandle() COMMA_LOCKVAL_SRC_POS);
+            m->allSharedFolders.addChild(pSharedFolder);
+            alock.release();
+        }
+
         /* net services - nat networks */
         for (settings::NATNetworksList::const_iterator it = m->pMainConfigFile->llNATNetworks.begin();
@@ -1502,7 +1518,11 @@
 HRESULT VirtualBox::getSharedFolders(std::vector<ComPtr<ISharedFolder> > &aSharedFolders)
 {
-    NOREF(aSharedFolders);
-
-    return setError(E_NOTIMPL, tr("Not yet implemented"));
+    AutoReadLock al(m->allSharedFolders.getLockHandle() COMMA_LOCKVAL_SRC_POS);
+    aSharedFolders.resize(m->allSharedFolders.size());
+    size_t i = 0;
+    for (SharedFoldersOList::const_iterator it= m->allSharedFolders.begin();
+         it!= m->allSharedFolders.end(); ++it, ++i)
+         (*it).queryInterfaceTo(aSharedFolders[i].asOutParam());
+    return S_OK;
 }
 
@@ -2780,17 +2800,79 @@
                                        const com::Utf8Str &aAutoMountPoint)
 {
-    NOREF(aName);
-    NOREF(aHostPath);
-    NOREF(aWritable);
-    NOREF(aAutomount);
-    NOREF(aAutoMountPoint);
-
-    return setError(E_NOTIMPL, tr("Not yet implemented"));
+    LogFlowThisFunc(("Entering for '%s' -> '%s'\n", aName.c_str(), aHostPath.c_str()));
+
+    ComPtr<ISharedFolder> found;
+    HRESULT hrc = i_findSharedFolder(aName, found);
+    if (SUCCEEDED(hrc))
+        return setError(VBOX_E_OBJECT_IN_USE,
+                        tr("Shared folder named '%s' already exists"),
+                        aName.c_str());
+
+    ComObjPtr<SharedFolder> sharedFolder;
+    SymlinkPolicy_T enmSymlinkPolicy = SymlinkPolicy_None;
+    sharedFolder.createObject();
+    hrc = sharedFolder->init(this,
+                             aName,
+                             aHostPath,
+                             !!aWritable,
+                             !!aAutomount,
+                             aAutoMountPoint,
+                             true /* fFailOnError */,
+                             enmSymlinkPolicy);
+    if (FAILED(hrc)) return hrc;
+
+    AutoWriteLock alock(m->allSharedFolders.getLockHandle() COMMA_LOCKVAL_SRC_POS);
+    m->allSharedFolders.addChild(sharedFolder);
+    alock.release();
+    {
+        AutoWriteLock vboxLock(this COMMA_LOCKVAL_SRC_POS);
+        hrc = i_saveSettings();
+        vboxLock.release();
+
+        if (FAILED(hrc))
+        {
+            alock.acquire();
+            m->allSharedFolders.removeChild(sharedFolder);
+            alock.release();
+        }
+    }
+
+    i_onSharedFolderChanged();
+    LogFlowThisFunc(("Leaving for '%s' -> '%s'\n", aName.c_str(), aHostPath.c_str()));
+    return hrc;
 }
 
 HRESULT VirtualBox::removeSharedFolder(const com::Utf8Str &aName)
 {
-    NOREF(aName);
-    return setError(E_NOTIMPL, tr("Not yet implemented"));
+    LogFlowThisFunc(("Entering for '%s'\n", aName.c_str()));
+
+    ComPtr<ISharedFolder> sharedFolder;
+    HRESULT hrc = i_findSharedFolder(aName, sharedFolder);
+    if (FAILED(hrc))
+        return hrc;
+
+    ISharedFolder *aP = sharedFolder;
+    SharedFolder *aP2 = static_cast<SharedFolder *>(aP);
+    AutoWriteLock alock(m->allSharedFolders.getLockHandle() COMMA_LOCKVAL_SRC_POS);
+    m->allSharedFolders.removeChild(aP2);
+    alock.release();
+
+    {
+        AutoWriteLock vboxLock(this COMMA_LOCKVAL_SRC_POS);
+        hrc = i_saveSettings();
+        vboxLock.release();
+
+        if (FAILED(hrc))
+        {
+            alock.acquire();
+            m->allSharedFolders.addChild(aP2);
+            alock.release();
+        }
+    }
+
+    i_onSharedFolderChanged();
+    LogFlowThisFunc(("Leaving for '%s'\n", aName.c_str()));
+
+    return hrc;
 }
 
@@ -3622,4 +3704,27 @@
     AssertComRCReturnVoid(hrc);
     i_postEvent(new AsyncEvent(this, ptrEvent));
+}
+
+/**
+ *  @note Locks this object for reading.
+ */
+void VirtualBox::i_onSharedFolderChanged()
+{
+    LogFlowThisFunc(("\n"));
+
+    AutoCaller autoCaller(this);
+    AssertComRCReturnVoid(autoCaller.hrc());
+
+    SessionMachinesList aMachines;
+    i_getOpenedMachines(aMachines, NULL);
+    for (SessionMachinesList::iterator it = aMachines.begin();
+         it != aMachines.end();
+         ++it)
+    {
+        ComObjPtr<SessionMachine> &pMachine = *it;
+        AutoReadLock mlock(pMachine COMMA_LOCKVAL_SRC_POS);
+        pMachine->i_onSharedFolderChange(TRUE);
+    }
+    aMachines.clear();
 }
 
@@ -4555,4 +4660,41 @@
 }
 
+/**
+ *  Searches for a shared folder with the given logical name
+ *  in the collection of shared folders.
+ *
+ *  @param aName            logical name of the shared folder
+ *  @param aSharedFolder    where to return the found object
+ *
+ *  @return S_OK, E_INVALIDARG or VBOX_E_OBJECT_NOT_FOUND when not found.
+ *
+ *  @note must be called from under the object's lock
+ */
+HRESULT VirtualBox::i_findSharedFolder(const Utf8Str &aName,
+                                       ComPtr<ISharedFolder> &aSharedFolder)
+{
+    ComObjPtr<SharedFolder> found;
+
+    AutoReadLock alock(m->allSharedFolders.getLockHandle() COMMA_LOCKVAL_SRC_POS);
+
+    for (SharedFoldersOList::const_iterator it = m->allSharedFolders.begin();
+        it != m->allSharedFolders.end();
+        ++it)
+    {
+        Bstr bstrSharedFolderName;
+        HRESULT hrc = (*it)->COMGETTER(Name)(bstrSharedFolderName.asOutParam());
+        if (FAILED(hrc)) return hrc;
+
+        if (Utf8Str(bstrSharedFolderName) == aName)
+        {
+            found = *it;
+            break;
+        }
+    }
+    if (!found)
+        return VBOX_E_OBJECT_NOT_FOUND;
+    return found.queryInterfaceTo(aSharedFolder.asOutParam());
+}
+
 /* Look for a GuestOSType object */
 HRESULT VirtualBox::i_findGuestOSType(const Utf8Str &strOSType,
@@ -5244,4 +5386,17 @@
                 if (FAILED(hrc)) throw hrc;
                 m->pMainConfigFile->llDhcpServers.push_back(d);
+            }
+        }
+        m->pMainConfigFile->llGlobalSharedFolders.clear();
+        {
+            AutoReadLock sharedFolderLock(m->allSharedFolders.getLockHandle() COMMA_LOCKVAL_SRC_POS);
+            for (SharedFoldersOList::const_iterator it = m->allSharedFolders.begin();
+                 it != m->allSharedFolders.end();
+                 ++it)
+            {
+                settings::SharedFolder sf;
+                hrc = (*it)->i_saveSettings(sf);
+                if (FAILED(hrc)) throw hrc;
+                m->pMainConfigFile->llGlobalSharedFolders.push_back(sf);
             }
         }
Index: trunk/src/VBox/Main/xml/Settings.cpp
===================================================================
--- trunk/src/VBox/Main/xml/Settings.cpp	(revision 108045)
+++ trunk/src/VBox/Main/xml/Settings.cpp	(revision 108046)
@@ -1648,4 +1648,30 @@
 }
 
+/**
+ * Constructor. Needs to set sane defaults which stand the test of time.
+ */
+SharedFolder::SharedFolder() :
+    fWritable(false),
+    fAutoMount(false),
+    enmSymlinkPolicy(SymlinkPolicy_None)
+{
+}
+
+/**
+ * Comparison operator. This gets called from MachineConfigFile::operator==,
+ * which in turn gets called from Machine::saveSettings to figure out whether
+ * machine settings have really changed and thus need to be written out to disk.
+ */
+bool SharedFolder::operator==(const SharedFolder &g) const
+{
+    return (this == &g)
+        || (   strName           == g.strName
+            && strHostPath       == g.strHostPath
+            && fWritable         == g.fWritable
+            && fAutoMount        == g.fAutoMount
+            && strAutoMountPoint == g.strAutoMountPoint
+            && enmSymlinkPolicy  == g.enmSymlinkPolicy);
+}
+
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -2098,4 +2124,42 @@
                 throw ConfigFileError(this, pelmNet, N_("Required NATNetwork/@networkName, @gateway, @network,@advertiseDefaultIpv6Route , @needDhcp or @enabled attribute is missing"));
         }
+    }
+}
+
+/**
+ * Reads in the \<SharedFolders\> chunk.
+ * @param elmSharedFolders
+ */
+void MainConfigFile::readSharedFolders(const xml::ElementNode &elmSharedFolders)
+{
+    xml::NodesLoop nl1(elmSharedFolders, "SharedFolder");
+    const xml::ElementNode *pelmFolder;
+    while ((pelmFolder = nl1.forAllNodes()))
+    {
+        SharedFolder sf;
+        pelmFolder->getAttributeValue("name", sf.strName);
+        pelmFolder->getAttributeValue("hostPath", sf.strHostPath);
+        pelmFolder->getAttributeValue("writable", sf.fWritable);
+        pelmFolder->getAttributeValue("autoMount", sf.fAutoMount);
+        pelmFolder->getAttributeValue("autoMountPoint", sf.strAutoMountPoint);
+
+        Utf8Str strTemp;
+        if (pelmFolder->getAttributeValue("symlinkPolicy", strTemp))
+        {
+            if (strTemp == "forbidden")
+                sf.enmSymlinkPolicy = SymlinkPolicy_Forbidden;
+            else if (strTemp == "subtree")
+                sf.enmSymlinkPolicy = SymlinkPolicy_AllowedInShareSubtree;
+            else if (strTemp == "relative")
+                sf.enmSymlinkPolicy = SymlinkPolicy_AllowedToRelativeTargets;
+            else if (strTemp == "any")
+                sf.enmSymlinkPolicy = SymlinkPolicy_AllowedToAnyTarget;
+            else
+                throw ConfigFileError(this,
+                                      pelmFolder,
+                                      N_("Invalid value '%s' in SharedFolder/@symlinkPolicy attribute"),
+                                      strTemp.c_str());
+        }
+        llGlobalSharedFolders.push_back(sf);
     }
 }
@@ -2433,4 +2497,6 @@
                         }
                     }
+                    else if (pelmGlobalChild->nameEquals("SharedFolders"))
+                        readSharedFolders(*pelmGlobalChild);
                     else if (pelmGlobalChild->nameEquals("USBDeviceFilters"))
                         readUSBDeviceFilters(*pelmGlobalChild, host.llUSBDeviceFilters);
@@ -2508,4 +2574,11 @@
             m->sv = SettingsVersion_v1_14;
     }
+    if (m->sv < SettingsVersion_v1_20)
+    {
+        // VirtualBox 7.1 adds global shared folders.
+        if (!llGlobalSharedFolders.empty())
+            m->sv = SettingsVersion_v1_20;
+    }
+
 }
 
@@ -2623,4 +2696,35 @@
     }
 #endif /* VBOX_WITH_CLOUD_NET */
+
+xml::ElementNode *pelmSharedFolders = pelmGlobal->createChild("SharedFolders");
+    if (!llGlobalSharedFolders.empty())
+    {
+        for (SharedFoldersList::const_iterator it = llGlobalSharedFolders.begin();
+             it != llGlobalSharedFolders.end();
+             ++it)
+        {
+            const SharedFolder &sf = *it;
+            xml::ElementNode *pelmThis = pelmSharedFolders->createChild("SharedFolder");
+            pelmThis->setAttribute("name", sf.strName);
+            pelmThis->setAttribute("hostPath", sf.strHostPath);
+            pelmThis->setAttribute("writable", sf.fWritable);
+            pelmThis->setAttribute("autoMount", sf.fAutoMount);
+            if (sf.strAutoMountPoint.isNotEmpty())
+                pelmThis->setAttribute("autoMountPoint", sf.strAutoMountPoint);
+            const char *pcszSymlinkPolicy;
+            if (sf.enmSymlinkPolicy != SymlinkPolicy_None)
+            {
+                switch (sf.enmSymlinkPolicy)
+                {
+                    default: /*case SymlinkPolicy_Forbidden:*/    pcszSymlinkPolicy = "forbidden";  break;
+                    case SymlinkPolicy_AllowedInShareSubtree:     pcszSymlinkPolicy = "subtree";    break;
+                    case SymlinkPolicy_AllowedToRelativeTargets:  pcszSymlinkPolicy = "relative";   break;
+                    case SymlinkPolicy_AllowedToAnyTarget:        pcszSymlinkPolicy = "any";        break;
+                }
+                pelmThis->setAttribute("symlinkPolicy", pcszSymlinkPolicy);
+            }
+
+        }
+    }
 
 #ifdef VBOX_WITH_UPDATE_AGENT
@@ -3789,29 +3893,4 @@
 }
 
-/**
- * Constructor. Needs to set sane defaults which stand the test of time.
- */
-SharedFolder::SharedFolder() :
-    fWritable(false),
-    fAutoMount(false),
-    enmSymlinkPolicy(SymlinkPolicy_None)
-{
-}
-
-/**
- * Comparison operator. This gets called from MachineConfigFile::operator==,
- * which in turn gets called from Machine::saveSettings to figure out whether
- * machine settings have really changed and thus need to be written out to disk.
- */
-bool SharedFolder::operator==(const SharedFolder &g) const
-{
-    return (this == &g)
-        || (   strName           == g.strName
-            && strHostPath       == g.strHostPath
-            && fWritable         == g.fWritable
-            && fAutoMount        == g.fAutoMount
-            && strAutoMountPoint == g.strAutoMountPoint
-            && enmSymlinkPolicy  == g.enmSymlinkPolicy);
-}
 
 /**
Index: trunk/src/VBox/Main/xml/VirtualBox-settings.xsd
===================================================================
--- trunk/src/VBox/Main/xml/VirtualBox-settings.xsd	(revision 108045)
+++ trunk/src/VBox/Main/xml/VirtualBox-settings.xsd	(revision 108046)
@@ -571,4 +571,5 @@
       </xsd:complexType>
     </xsd:element>
+    <xsd:element name="SharedFolders" type="TSharedFolders" minOccurs="0"/>
     <xsd:element name="USBDeviceFilters">
       <xsd:complexType>
