Index: trunk/src/VBox/Main/src-client/ConsoleImpl.cpp
===================================================================
--- trunk/src/VBox/Main/src-client/ConsoleImpl.cpp	(revision 35755)
+++ trunk/src/VBox/Main/src-client/ConsoleImpl.cpp	(revision 35757)
@@ -1384,5 +1384,6 @@
                                          strHostPath,
                                          writable,
-                                         autoMount);
+                                         autoMount,
+                                         false /* fFailOnError */);
         AssertComRCReturn(rc, VERR_INTERNAL_ERROR);
 
@@ -2851,4 +2852,6 @@
     CheckComArgStrNotEmptyOrNull(aHostPath);
 
+    LogFlowThisFunc(("Entering for '%ls' -> '%ls'\n", aName, aHostPath));
+
     AutoCaller autoCaller(this);
     if (FAILED(autoCaller.rc())) return autoCaller.rc();
@@ -2877,9 +2880,14 @@
     if (SUCCEEDED(rc))
         return setError(VBOX_E_FILE_ERROR,
-            tr("Shared folder named '%s' already exists"),
-            strName.c_str());
+                        tr("Shared folder named '%s' already exists"),
+                        strName.c_str());
 
     pSharedFolder.createObject();
-    rc = pSharedFolder->init(this, strName, strHostPath, aWritable, aAutoMount);
+    rc = pSharedFolder->init(this,
+                             strName,
+                             strHostPath,
+                             aWritable,
+                             aAutoMount,
+                             true /* fFailOnError */);
     if (FAILED(rc)) return rc;
 
@@ -2914,4 +2922,6 @@
     fireSharedFolderChangedEvent(mEventSource, Scope_Session);
 
+    LogFlowThisFunc(("Leaving for '%ls' -> '%ls'\n", aName, aHostPath));
+
     return rc;
 }
@@ -2923,4 +2933,6 @@
     AutoCaller autoCaller(this);
     if (FAILED(autoCaller.rc())) return autoCaller.rc();
+
+    LogFlowThisFunc(("Entering for '%ls'\n", aName));
 
     Utf8Str strName(aName);
@@ -2976,4 +2988,6 @@
     /* notify console callbacks after the folder is removed to the list */
     fireSharedFolderChangedEvent(mEventSource, Scope_Session);
+
+    LogFlowThisFunc(("Leaving for '%ls'\n", aName));
 
     return rc;
@@ -6195,4 +6209,6 @@
                  isWriteLockOnCurrentThread(), E_FAIL);
 
+    LogFlowThisFunc(("Entering\n"));
+
     /* protect mpVM (if not NULL) */
     AutoVMCallerQuietWeak autoVMCaller(this);
@@ -6205,107 +6221,121 @@
                   && m_pVMMDev->isShFlActive();
 
-    if (aGlobal)
-    {
-        /// @todo grab & process global folders when they are done
-    }
-    else
-    {
-        SharedFolderDataMap oldFolders;
-        if (online)
-            oldFolders = m_mapMachineSharedFolders;
-
-        m_mapMachineSharedFolders.clear();
-
-        SafeIfaceArray<ISharedFolder> folders;
-        rc = mMachine->COMGETTER(SharedFolders)(ComSafeArrayAsOutParam(folders));
-        AssertComRCReturnRC(rc);
-
-        for (size_t i = 0; i < folders.size(); ++i)
-        {
-            ComPtr<ISharedFolder> pSharedFolder = folders[i];
-
-            Bstr bstrName;
-            Bstr bstrHostPath;
-            BOOL writable;
-            BOOL autoMount;
-
-            rc = pSharedFolder->COMGETTER(Name)(bstrName.asOutParam());
-            if (FAILED(rc)) break;
-            Utf8Str strName(bstrName);
-
-            rc = pSharedFolder->COMGETTER(HostPath)(bstrHostPath.asOutParam());
-            if (FAILED(rc)) break;
-            Utf8Str strHostPath(bstrHostPath);
-
-            rc = pSharedFolder->COMGETTER(Writable)(&writable);
-            if (FAILED(rc)) break;
-
-            rc = pSharedFolder->COMGETTER(AutoMount)(&autoMount);
-            if (FAILED(rc)) break;
-
-            m_mapMachineSharedFolders.insert(std::make_pair(strName,
-                                                            SharedFolderData(strHostPath, writable, autoMount)));
-
-            /* send changes to HGCM if the VM is running */
-            /// @todo umoeller report errors as runtime warnings through VMSetError
+    try
+    {
+        if (aGlobal)
+        {
+            /// @todo grab & process global folders when they are done
+        }
+        else
+        {
+            SharedFolderDataMap oldFolders;
+            if (online)
+                oldFolders = m_mapMachineSharedFolders;
+
+            m_mapMachineSharedFolders.clear();
+
+            SafeIfaceArray<ISharedFolder> folders;
+            rc = mMachine->COMGETTER(SharedFolders)(ComSafeArrayAsOutParam(folders));
+            if (FAILED(rc)) throw rc;
+
+            for (size_t i = 0; i < folders.size(); ++i)
+            {
+                ComPtr<ISharedFolder> pSharedFolder = folders[i];
+
+                Bstr bstrName;
+                Bstr bstrHostPath;
+                BOOL writable;
+                BOOL autoMount;
+
+                rc = pSharedFolder->COMGETTER(Name)(bstrName.asOutParam());
+                if (FAILED(rc)) throw rc;
+                Utf8Str strName(bstrName);
+
+                rc = pSharedFolder->COMGETTER(HostPath)(bstrHostPath.asOutParam());
+                if (FAILED(rc)) throw rc;
+                Utf8Str strHostPath(bstrHostPath);
+
+                rc = pSharedFolder->COMGETTER(Writable)(&writable);
+                if (FAILED(rc)) throw rc;
+
+                rc = pSharedFolder->COMGETTER(AutoMount)(&autoMount);
+                if (FAILED(rc)) throw rc;
+
+                m_mapMachineSharedFolders.insert(std::make_pair(strName,
+                                                                SharedFolderData(strHostPath, writable, autoMount)));
+
+                /* send changes to HGCM if the VM is running */
+                /// @todo umoeller report errors as runtime warnings through VMSetError
+                if (online)
+                {
+                    SharedFolderDataMap::iterator it = oldFolders.find(strName);
+                    if (    it == oldFolders.end()
+                         || it->second.m_strHostPath != strHostPath)
+                    {
+                        /* a new machine folder is added or
+                         * the existing machine folder is changed */
+                        if (m_mapSharedFolders.find(strName) != m_mapSharedFolders.end())
+                            ; /* the console folder exists, nothing to do */
+                        else
+                        {
+                            /* remove the old machine folder (when changed)
+                             * or the global folder if any (when new) */
+                            if (    it != oldFolders.end()
+                                 || m_mapGlobalSharedFolders.find(strName) != m_mapGlobalSharedFolders.end()
+                               )
+                            {
+                                rc = removeSharedFolder(strName);
+                                if (FAILED(rc)) throw rc;
+                            }
+
+                            /* create the new machine folder */
+                            rc = createSharedFolder(strName,
+                                                    SharedFolderData(strHostPath,
+                                                                     writable,
+                                                                     autoMount));
+                            if (FAILED(rc)) throw rc;
+                        }
+                    }
+                    /* forget the processed (or identical) folder */
+                    if (it != oldFolders.end())
+                        oldFolders.erase(it);
+                }
+            }
+
+            /* process outdated (removed) folders */
             if (online)
             {
-                SharedFolderDataMap::iterator it = oldFolders.find(strName);
-                if (    it == oldFolders.end()
-                     || it->second.m_strHostPath != strHostPath)
+                for (SharedFolderDataMap::const_iterator it = oldFolders.begin();
+                     it != oldFolders.end(); ++ it)
                 {
-                    /* a new machine folder is added or
-                     * the existing machine folder is changed */
-                    if (m_mapSharedFolders.find(strName) != m_mapSharedFolders.end())
+                    if (m_mapSharedFolders.find(it->first) != m_mapSharedFolders.end())
                         ; /* the console folder exists, nothing to do */
                     else
                     {
-                        /* remove the old machine folder (when changed)
-                         * or the global folder if any (when new) */
-                        if (    it != oldFolders.end()
-                             || m_mapGlobalSharedFolders.find(strName) != m_mapGlobalSharedFolders.end()
-                           )
-                            rc = removeSharedFolder(strName);
-                        /* create the new machine folder */
-                        rc = createSharedFolder(strName,
-                                                SharedFolderData(strHostPath,
-                                                                 writable,
-                                                                 autoMount));
+                        /* remove the outdated machine folder */
+                        rc = removeSharedFolder(it->first);
+                        if (FAILED(rc)) throw rc;
+
+                        /* create the global folder if there is any */
+                        SharedFolderDataMap::const_iterator git =
+                            m_mapGlobalSharedFolders.find(it->first);
+                        if (git != m_mapGlobalSharedFolders.end())
+                        {
+                            rc = createSharedFolder(git->first, git->second);
+                            if (FAILED(rc)) throw rc;
+                        }
                     }
                 }
-                /* forget the processed (or identical) folder */
-                if (it != oldFolders.end())
-                    oldFolders.erase(it);
-
-                rc = S_OK;
             }
         }
-
-        AssertComRCReturnRC(rc);
-
-        /* process outdated (removed) folders */
-        /// @todo report errors as runtime warnings through VMSetError
+    }
+    catch (HRESULT rc2)
+    {
         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
-                {
-                    /* remove the outdated machine folder */
-                    rc = removeSharedFolder(it->first);
-                    /* create the global folder if there is any */
-                    SharedFolderDataMap::const_iterator git =
-                        m_mapGlobalSharedFolders.find(it->first);
-                    if (git != m_mapGlobalSharedFolders.end())
-                        rc = createSharedFolder(git->first, git->second);
-                }
-            }
-
-            rc = S_OK;
-        }
-    }
+            setVMRuntimeErrorCallbackF(mpVM, this, 0, "BrokenSharedFolder",
+                                       N_("Broken shared folder!"));
+    }
+
+    LogFlowThisFunc(("Leaving\n"));
 
     return rc;
@@ -6364,4 +6394,27 @@
 
     Log(("Adding shared folder '%s' -> '%s'\n", strName.c_str(), aData.m_strHostPath.c_str()));
+
+    // check whether the path is valid and exists
+    /* Check whether the path is full (absolute) */
+    char hostPathFull[RTPATH_MAX];
+    int vrc = RTPathAbsEx(NULL,
+                          aData.m_strHostPath.c_str(),
+                          hostPathFull,
+                          sizeof(hostPathFull));
+    if (RT_FAILURE(vrc))
+        return setError(E_INVALIDARG,
+                        tr("Invalid shared folder path: '%s' (%Rrc)"),
+                        aData.m_strHostPath.c_str(), vrc);
+
+    if (RTPathCompare(aData.m_strHostPath.c_str(), hostPathFull) != 0)
+        return setError(E_INVALIDARG,
+                        tr("Shared folder path '%s' is not absolute"),
+                        aData.m_strHostPath.c_str());
+    if (!RTPathExists(hostPathFull))
+        return setError(E_INVALIDARG,
+                        tr("Shared folder path '%s' does not exist on the host"),
+                        aData.m_strHostPath.c_str());
+
+    // now that we know the path is good, give it to HGCM
 
     Bstr bstrName(strName);
@@ -6411,7 +6464,7 @@
     parms[3].u.uint32 = aData.m_fAutoMount;
 
-    int vrc = m_pVMMDev->hgcmHostCall("VBoxSharedFolders",
-                                      SHFL_FN_ADD_MAPPING,
-                                      SHFL_CPARMS_ADD_MAPPING2, &parms[0]);
+    vrc = m_pVMMDev->hgcmHostCall("VBoxSharedFolders",
+                                  SHFL_FN_ADD_MAPPING,
+                                  SHFL_CPARMS_ADD_MAPPING2, &parms[0]);
     RTMemFree(pFolderName);
     RTMemFree(pMapName);
@@ -7830,9 +7883,18 @@
                     {
                         const SharedFolderData &d = it->second;
-                        rc = pConsole->createSharedFolder(it->first,
-                                                          d);
-                        if (FAILED(rc)) break;
+                        rc = pConsole->createSharedFolder(it->first, d);
+                        if (FAILED(rc))
+                        {
+                            ErrorInfoKeeper eik;
+                            setVMRuntimeErrorCallbackF(pVM, pConsole, 0, "BrokenSharedFolder",
+                                                       N_("The shared folder '%s' could not be set up: %ls.\n"
+                                                          "The shared folder setup will not be complete. It is recommended to power down the virtual machine and "
+                                                          "fix the shared folder settings while the machine is not running."),
+                                                       it->first.c_str(), eik.getText().raw());
+                            break;
+                        }
                     }
-                    if (FAILED(rc)) break;
+                    if (FAILED(rc))
+                        rc = S_OK;          // do not fail with broken shared folders
 
                     /* enter the lock again */
