Index: /trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControlExec.cpp
===================================================================
--- /trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControlExec.cpp	(revision 33695)
+++ /trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControlExec.cpp	(revision 33696)
@@ -1028,7 +1028,56 @@
 
 
+/** @todo Maybe we want to have an own IPRT function for that! */
+int VBoxServiceControlExecMakeFullPath(const char *pszPath, char *pszExpanded, size_t cbExpanded)
+{
+    int rc = VINF_SUCCESS;
+#ifdef RT_OS_WINDOWS
+    if (!ExpandEnvironmentStrings(pszPath, pszExpanded, cbExpanded))
+        rc = RTErrConvertFromWin32(GetLastError());
+#else
+    /* No expansion for non-Windows yet. */
+    rc = RTStrCopy(pszExpanded, cbExpanded, pszPath);
+#endif
+    return rc;
+}
+
+
+int VBoxServiceControlExecResolveExecutable(const char *pszFileName, char *pszResolved, size_t cbResolved)
+{
+    int rc = VINF_SUCCESS;
+
+    /* Search the path of our executable. */
+    char szVBoxService[RTPATH_MAX];
+    if (RTProcGetExecutableName(szVBoxService, sizeof(szVBoxService)))
+    {
+        char *pszExecResolved = NULL;
+        if (   (g_pszProgName && RTStrICmp(pszFileName, g_pszProgName) == 0)
+            || !RTStrICmp(pszFileName, VBOXSERVICE_NAME))
+        {
+            /* We just want to execute VBoxService (no toolbox). */
+            pszExecResolved = RTStrDup(szVBoxService);
+        }
 #ifdef VBOXSERVICE_TOOLBOX
-/**
- * Constructs the argv command line of a VBoxService toolbox program
+        else if (RTStrStr(pszFileName, "vbox_") == pszFileName)
+        {
+            /* We want to use the internal toolbox (all internal
+             * tools are starting with "vbox_" (e.g. "vbox_cat"). */
+            pszExecResolved = RTStrDup(szVBoxService);
+        }
+#endif
+        else /* Nothing to resolve, copy original. */
+            pszExecResolved = RTStrDup(pszFileName);
+        AssertPtr(pszExecResolved);
+
+        rc = VBoxServiceControlExecMakeFullPath(pszExecResolved, pszResolved, cbResolved);
+        RTStrFree(pszExecResolved);
+    }
+    return rc;
+}
+
+
+#ifdef VBOXSERVICE_TOOLBOX
+/**
+ * Constructs the argv command line of a VBoxService program
  * by first appending the full path of VBoxService along  with the given
  * tool name (e.g. "vbox_cat") + the tool's actual command line parameters.
@@ -1040,6 +1089,6 @@
  *                          Needs to be freed with RTGetOptArgvFree.
  */
-int VBoxServiceControlExecPrepareToolboxArgv(const char *pszFileName,
-                                             const char * const *papszArgs, char ***ppapszArgv)
+int VBoxServiceControlExecPrepareArgv(const char *pszFileName,
+                                      const char * const *papszArgs, char ***ppapszArgv)
 {
     AssertPtrReturn(pszFileName, VERR_INVALID_PARAMETER);
@@ -1052,15 +1101,20 @@
     if (RT_SUCCESS(rc))
     {
-        char *pszNewArgs;
         /*
          * Construct the new command line by appending the actual
          * tool name to new process' command line.
          */
-        if (RTStrAPrintf(&pszNewArgs, "%s %s", pszFileName, pszArgs))
-        {
-            int iNumArgsIgnored;
-            rc = RTGetOptArgvFromString(ppapszArgv, &iNumArgsIgnored,
-                                        pszNewArgs, NULL /* Use standard separators. */);
-            RTStrFree(pszNewArgs);
+        char szArgsExp[RTPATH_MAX];
+        rc = VBoxServiceControlExecMakeFullPath(pszArgs, szArgsExp, sizeof(szArgsExp));
+        if (RT_SUCCESS(rc))
+        {
+            char *pszNewArgs;
+            if (RTStrAPrintf(&pszNewArgs, "%s %s", pszFileName, szArgsExp))
+            {
+                int iNumArgsIgnored;
+                rc = RTGetOptArgvFromString(ppapszArgv, &iNumArgsIgnored,
+                                            pszNewArgs, NULL /* Use standard separators. */);
+                RTStrFree(pszNewArgs);
+            }
         }
         RTStrFree(pszArgs);
@@ -1118,56 +1172,30 @@
     }
 #endif /* RT_OS_WINDOWS */
-#ifdef VBOXSERVICE_TOOLBOX
-    /* Search the path of our executable. */
-    char szVBoxService[RTPATH_MAX];
-    if (RTProcGetExecutableName(szVBoxService, sizeof(szVBoxService)))
-    {
-        char *pszCmdTool = NULL;
-        char **papszArgsTool = NULL;
-        if (   (g_pszProgName && RTStrICmp(pszExec, g_pszProgName) == 0)
-            || !RTStrICmp(pszExec, VBOXSERVICE_NAME))
-        {
-            /* We just want to execute VBoxService (no toolbox). */
-            pszCmdTool = RTStrDup(szVBoxService);
-        }
-        else if (RTStrStr(pszExec, "vbox_") == pszExec)
-        {
-            /* We want to use the internal toolbox (all internal
-             * tools are starting with "vbox_" (e.g. "vbox_cat"). */
-            pszCmdTool = RTStrDup(szVBoxService);
-            rc = VBoxServiceControlExecPrepareToolboxArgv(pszCmdTool, papszArgs, &papszArgsTool);
-        }
-
-        if (RT_SUCCESS(rc) && pszCmdTool)
-        {
-            /* Disable service flag bit, because we're executing the internal
-             * tool with the profile which was used to start VBoxService. */
-            fFlags &= ~RTPROC_FLAGS_SERVICE;
-
-            rc = RTProcCreateEx(pszCmdTool, papszArgsTool ? papszArgsTool : papszArgs,
-                                hEnv, fFlags,
+
+    /*
+     * Do the environment variables expansion on executable and arguments.
+     */
+    char szExecExp[RTPATH_MAX];
+    rc = VBoxServiceControlExecResolveExecutable(pszExec, szExecExp, sizeof(szExecExp));
+    if (RT_SUCCESS(rc))
+    {
+        char **papszArgsExp;
+        rc = VBoxServiceControlExecPrepareArgv(szExecExp, papszArgs, &papszArgsExp);
+        if (RT_SUCCESS(rc))
+        {
+            /* If no user name specified run with current credentials.
+             * This is prohibited via official Main API! */
+            if (!strlen(pszAsUser))
+                fFlags &= ~RTPROC_FLAGS_SERVICE;
+
+            /* Do normal execution. */
+            rc = RTProcCreateEx(szExecExp, papszArgsExp, hEnv, fFlags,
                                 phStdIn, phStdOut, phStdErr,
                                 strlen(pszAsUser) ? pszAsUser : NULL,
                                 strlen(pszPassword) ? pszPassword : NULL,
                                 phProcess);
-            if (papszArgsTool)
-                RTGetOptArgvFree(papszArgsTool);
-            RTStrFree(pszCmdTool);
-            return rc;
-        }
-    }
-#endif
-
-    /* If no user name specified run with current credentials.
-     * This is prohibited via official Main API! */
-    if (!strlen(pszAsUser))
-        fFlags &= ~RTPROC_FLAGS_SERVICE;
-
-    /* Do normal execution. */
-    rc = RTProcCreateEx(pszExec, papszArgs, hEnv, fFlags,
-                        phStdIn, phStdOut, phStdErr,
-                        strlen(pszAsUser) ? pszAsUser : NULL,
-                        strlen(pszPassword) ? pszPassword : NULL,
-                        phProcess);
+        }
+        RTGetOptArgvFree(papszArgsExp);
+    }
     return rc;
 }
Index: /trunk/src/VBox/Frontends/VirtualBox/src/runtime/UISession.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/runtime/UISession.cpp	(revision 33695)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/runtime/UISession.cpp	(revision 33696)
@@ -361,45 +361,29 @@
      */
     bool fDoMount = false;
-    /*
-     * If the already installed Guest Additions indicate a
-     * high enough run level (at the moment this is level "Desktop",
-     * which means that a user has to be logged in to acknowledge
-     * WHQL popups), try an automatic Guest Additions update.
-     */
+
     CGuest guest = session().GetConsole().GetGuest();
-    QString osType = guest.GetOSTypeId();
-    ULONG ulGuestAdditionsRunLevel = guest.GetAdditionsRunLevel();
-    if (   ulGuestAdditionsRunLevel >= AdditionsRunLevelType_System // Desktop
-#if 1  /* Only Windows is supported at the moment! */
-        && (   osType.contains("Microsoft", Qt::CaseInsensitive)
-            || osType.contains("Windows", Qt::CaseInsensitive)
-           )
-#endif
-       )
-    {
 #ifdef DEBUG_andy
-        CProgress progressInstall = guest.UpdateGuestAdditions("c:\\Downloads\\VBoxGuestAdditions-r67158.iso");
+    CProgress progressInstall = guest.UpdateGuestAdditions("c:\\Downloads\\VBoxGuestAdditions-r67158.iso");
 #else
-        CProgress progressInstall = guest.UpdateGuestAdditions(strSource);
-#endif
-        bool fResult = guest.isOk();
-        if (fResult)
-        {
-            vboxProblem().showModalProgressDialog(progressInstall, tr("Install"),
-                                                  mainMachineWindow(), 0 /* No delay */);
-            if (progressInstall.GetCanceled())
-                return;
-            if (!progressInstall.isOk() || progressInstall.GetResultCode() != 0)
-            {
+    CProgress progressInstall = guest.UpdateGuestAdditions(strSource);
+#endif
+    bool fResult = guest.isOk();
+    if (fResult)
+    {
+        vboxProblem().showModalProgressDialog(progressInstall, tr("Install"),
+                                              mainMachineWindow(), 0 /* No delay */);
+        if (progressInstall.GetCanceled())
+            return;
+
+        HRESULT rc = progressInstall.GetResultCode();
+        if (!progressInstall.isOk() || rc != S_OK)
+        {
+            /* If we got back a VBOX_E_NOT_SUPPORTED we don't complain (guest OS
+             * simply isn't supported yet), so silently fall back to "old" .ISO
+             * mounting method. */
+            if (rc != VBOX_E_NOT_SUPPORTED)
                 vboxProblem().cannotUpdateGuestAdditions(progressInstall, mainMachineWindow());
-                fDoMount = true; /* Since automatic updating failed, fall back to .ISO mounting. */
-            }
-        }
-    }
-    else
-    {
-        /* Running guest OS not suitable (yet) for automatic updating,
-         * fall back to .ISO mounting. */
-        fDoMount = true;
+            fDoMount = true; /* Since automatic updating failed, fall back to .ISO mounting. */
+        }
     }
 
Index: /trunk/src/VBox/Main/GuestImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/GuestImpl.cpp	(revision 33695)
+++ /trunk/src/VBox/Main/GuestImpl.cpp	(revision 33696)
@@ -163,11 +163,17 @@
         Guest *pGuest = aTask->pGuest;
         AssertPtr(pGuest);
-        /*Console *pConsole = pGuest->mParent;
-        AssertPtr(pConsole);
-        Console *pMachine = pConsole->machine();
-        AssertPtr(pMachine);*/
 
         if (aTask->progress)
             aTask->progress->SetCurrentOperationProgress(10);
+
+        bool fIsWindows = false;
+        Utf8Str osType = pGuest->mData.mOSTypeId;
+        if (   osType.contains("Microsoft", Utf8Str::CaseInsensitive)
+            || osType.contains("Windows", Utf8Str::CaseInsensitive))
+        {
+            fIsWindows = true; /* We have a Windows guest. */
+        }
+        else /* Everything else is not supported (yet). */
+            throw setError(VBOX_E_NOT_SUPPORTED, tr("Guest OS not supported for automatic Guest Additions updating"));
 
         /*
@@ -176,7 +182,5 @@
          */
         Utf8Str installerImage;
-        Utf8Str osType = pGuest->mData.mOSTypeId;
-        if (   osType.contains("Microsoft", Utf8Str::CaseInsensitive)
-            || osType.contains("Windows", Utf8Str::CaseInsensitive))
+        if (fIsWindows)
         {
             if (osType.contains("64", Utf8Str::CaseInsensitive))
@@ -187,8 +191,5 @@
              * no further path processing needs to be done (yet). */
         }
-
-        /* No (suited) installer found? Bail out. */
-        if (installerImage.isEmpty())
-            throw setError(VBOX_E_FILE_ERROR, tr("Guest OS not supported for automatic Guest Additions updating yet"));
+        Assert(!installerImage.isEmpty());
 
         /*
@@ -197,5 +198,9 @@
         RTISOFSFILE iso;
         int vrc = RTIsoFsOpen(&iso, aTask->strSource.c_str());
-        if (RT_SUCCESS(vrc))
+        if (RT_FAILURE(vrc))
+        {
+            rc = setError(VBOX_E_FILE_ERROR, tr("Invalid installation medium detected"));
+        }
+        else
         {
             uint32_t cbOffset;
@@ -209,8 +214,6 @@
             }
 
-            /** @todo Only Windows! Don't use percent (like %TEMP%) env vars -- Windows
-             *        will quote it like "%TEMP%" which results in a *not* working command
-             *        line! */
-            Utf8Str strInstallerPath = "C:\\Windows\\VBoxWindowsAdditions.exe";
+            /* Specify the ouput path on the guest side. */
+            Utf8Str strInstallerPath = "%TEMP%\\VBoxWindowsAdditions.exe";
 
             if (RT_FAILURE(vrc))
@@ -219,5 +222,5 @@
                 {
                     case VERR_FILE_NOT_FOUND:
-                        rc = setError(VBOX_E_IPRT_ERROR, tr("Installer file was not found on medium"));
+                        rc = setError(VBOX_E_IPRT_ERROR, tr("Setup file was not found on installation medium"));
                         break;
 
@@ -237,12 +240,7 @@
                 com::SafeArray<IN_BSTR> env;
 
-                char szOutput[RTPATH_MAX];
-                if (RTStrPrintf(szOutput, sizeof(szOutput), "--output=%s", strInstallerPath.c_str()))
-                {
-                    args.push_back(Bstr(VBOXSERVICE_TOOL_CAT).raw()); /* The actual (internal) tool to use (as argv[0]). */
-                    args.push_back(Bstr(szOutput).raw());             /* We want to write a file ... */
-                }
-                else
-                    rc = setError(VBOX_E_IPRT_ERROR, tr("Error preparing command line fopr copy operation"));
+                args.push_back(Bstr(VBOXSERVICE_TOOL_CAT).raw());     /* The actual (internal) tool to use (as argv[0]). */
+                args.push_back(Bstr("--output").raw());               /* We want to write a file ... */
+                args.push_back(Bstr(strInstallerPath.c_str()).raw()); /* ... with this path. */
 
                 if (SUCCEEDED(rc))
