Index: /trunk/src/VBox/Frontends/VBoxManage/VBoxManageMisc.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VBoxManage/VBoxManageMisc.cpp	(revision 35522)
+++ /trunk/src/VBox/Frontends/VBoxManage/VBoxManageMisc.cpp	(revision 35523)
@@ -859,6 +859,14 @@
         ComPtr<IProgress> ptrProgress;
         CHECK_ERROR2_RET(ptrExtPackFile, Install(fReplace, NULL, ptrProgress.asOutParam()), RTEXITCODE_FAILURE);
-        if (!ptrProgress.isNull())
-            CHECK_ERROR2_RET(ptrProgress, WaitForCompletion(-1), RTEXITCODE_FAILURE);
+        hrc = showProgress(ptrProgress);
+        if (FAILED(hrc))
+        {
+            com::ProgressErrorInfo ErrInfo(ptrProgress);
+            if (ErrInfo.isBasicAvailable())
+                RTMsgError("Failed to install \"%s\": %lS", szPath, ErrInfo.getText().raw());
+            else
+                RTMsgError("Failed to install \"%s\": No error message available!", szPath);
+            return RTEXITCODE_FAILURE;
+        }
         RTPrintf("Successfully installed \"%lS\".\n", bstrName.raw());
     }
@@ -898,6 +906,14 @@
         ComPtr<IProgress> ptrProgress;
         CHECK_ERROR2_RET(ptrExtPackMgr, Uninstall(bstrName.raw(), fForced, NULL, ptrProgress.asOutParam()), RTEXITCODE_FAILURE);
-        if (!ptrProgress.isNull())
-            CHECK_ERROR2_RET(ptrProgress, WaitForCompletion(-1), RTEXITCODE_FAILURE);
+        hrc = showProgress(ptrProgress);
+        if (FAILED(hrc))
+        {
+            com::ProgressErrorInfo ErrInfo(ptrProgress);
+            if (ErrInfo.isBasicAvailable())
+                RTMsgError("Failed to uninstall \"%s\": %lS", pszName, ErrInfo.getText().raw());
+            else
+                RTMsgError("Failed to uninstall \"%s\": No error message available!", pszName);
+            return RTEXITCODE_FAILURE;
+        }
         RTPrintf("Successfully uninstalled \"%s\".\n", pszName);
     }
Index: /trunk/src/VBox/Main/idl/VirtualBox.xidl
===================================================================
--- /trunk/src/VBox/Main/idl/VirtualBox.xidl	(revision 35522)
+++ /trunk/src/VBox/Main/idl/VirtualBox.xidl	(revision 35523)
@@ -14849,6 +14849,5 @@
       <param name="progess" type="IProgress" dir="return">
         <desc>
-          Progress object for the operation if it was decided that it should
-          be executed asynchronously - i.e. never in 4.0.0, but maybe in 4.0.x.
+          Progress object for the operation.
         </desc>
       </param>
@@ -14921,6 +14920,5 @@
       <param name="progess" type="IProgress" dir="return">
         <desc>
-          Progress object for the operation if it was decided that it should
-          be executed asynchronously - i.e. never in 4.0.0, but maybe in 4.0.x.
+          Progress object for the operation.
         </desc>
       </param>
Index: /trunk/src/VBox/Main/include/ExtPackManagerImpl.h
===================================================================
--- /trunk/src/VBox/Main/include/ExtPackManagerImpl.h	(revision 35522)
+++ /trunk/src/VBox/Main/include/ExtPackManagerImpl.h	(revision 35523)
@@ -46,5 +46,5 @@
     HRESULT     FinalConstruct();
     void        FinalRelease();
-    HRESULT     initWithFile(const char *a_pszFile, class ExtPackManager *a_pExtPackMgr);
+    HRESULT     initWithFile(const char *a_pszFile, class ExtPackManager *a_pExtPackMgr, VirtualBox *a_pVirtualBox);
     void        uninit();
     RTMEMEF_NEW_AND_DELETE_OPERATORS();
@@ -219,6 +219,8 @@
     /** @name Internal interfaces used by other Main classes.
      * @{ */
-    HRESULT     doInstall(ExtPackFile *a_pExtPackFile, bool a_fReplace, Utf8Str const *a_pstrDisplayInfo,
-                          IProgress **a_ppProgress);
+    static DECLCALLBACK(int) doInstallThreadProc(RTTHREAD hThread, void *pvJob);
+    HRESULT     doInstall(ExtPackFile *a_pExtPackFile, bool a_fReplace, Utf8Str const *a_pstrDisplayInfo);
+    static DECLCALLBACK(int) doUninstallThreadProc(RTTHREAD hThread, void *pvJob);
+    HRESULT     doUninstall(const Utf8Str *a_pstrName, bool a_fForcedRemoval, const Utf8Str *a_pstrDisplayInfo);
     void        callAllVirtualBoxReadyHooks(void);
     void        callAllConsoleReadyHooks(IConsole *a_pConsole);
Index: /trunk/src/VBox/Main/include/ExtPackUtil.h
===================================================================
--- /trunk/src/VBox/Main/include/ExtPackUtil.h	(revision 35522)
+++ /trunk/src/VBox/Main/include/ExtPackUtil.h	(revision 35523)
@@ -110,4 +110,5 @@
 
 
+void                VBoxExtPackInitDesc(PVBOXEXTPACKDESC a_pExtPackDesc);
 iprt::MiniString   *VBoxExtPackLoadDesc(const char *a_pszDir, PVBOXEXTPACKDESC a_pExtPackDesc, PRTFSOBJINFO a_pObjInfo);
 iprt::MiniString   *VBoxExtPackLoadDescFromVfsFile(RTVFSFILE hVfsFile, PVBOXEXTPACKDESC a_pExtPackDesc, PRTFSOBJINFO a_pObjInfo);
Index: /trunk/src/VBox/Main/src-all/ExtPackManagerImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/src-all/ExtPackManagerImpl.cpp	(revision 35522)
+++ /trunk/src/VBox/Main/src-all/ExtPackManagerImpl.cpp	(revision 35523)
@@ -44,4 +44,5 @@
 #include "AutoCaller.h"
 #include "Global.h"
+#include "ProgressImpl.h"
 #include "SystemPropertiesImpl.h"
 #include "VirtualBoxImpl.h"
@@ -94,4 +95,6 @@
     /** Pointer to the extension pack manager. */
     ComObjPtr<ExtPackManager> ptrExtPackMgr;
+    /** Pointer to the VirtualBox object so we can create a progress object. */
+    VirtualBox         *pVirtualBox;
 
     RTMEMEF_NEW_AND_DELETE_OPERATORS();
@@ -158,4 +161,42 @@
 };
 
+/**
+ * Extension pack installation job.
+ */
+typedef struct EXTPACKINSTALLJOB
+{
+    /** Smart pointer to the extension pack file. */
+    ComPtr<ExtPackFile>     ptrExtPackFile;
+    /** The replace argument. */
+    bool                    fReplace;
+    /** The display info argument.  */
+    Utf8Str                 strDisplayInfo;
+    /** Smart pointer to the extension manager. */
+    ComPtr<ExtPackManager>  ptrExtPackMgr;
+    /** Smart pointer to the progress object for this job. */
+    ComObjPtr<Progress>     ptrProgress;
+} EXTPACKINSTALLJOB;
+/** Pointer to an extension pack installation job. */
+typedef EXTPACKINSTALLJOB *PEXTPACKINSTALLJOB;
+
+/**
+ * Extension pack uninstallation job.
+ */
+typedef struct EXTPACKUNINSTALLJOB
+{
+    /** Smart pointer to the extension manager. */
+    ComPtr<ExtPackManager>  ptrExtPackMgr;
+    /** The name of the extension pack. */
+    Utf8Str                 strName;
+    /** The replace argument. */
+    bool                    fForcedRemoval;
+    /** The display info argument.  */
+    Utf8Str                 strDisplayInfo;
+    /** Smart pointer to the progress object for this job. */
+    ComObjPtr<Progress>     ptrProgress;
+} EXTPACKUNINSTALLJOB;
+/** Pointer to an extension pack uninstallation job. */
+typedef EXTPACKUNINSTALLJOB *PEXTPACKUNINSTALLJOB;
+
 
 DEFINE_EMPTY_CTOR_DTOR(ExtPackFile)
@@ -180,6 +221,7 @@
  * @param   a_pszFile       The path to the extension pack file.
  * @param   a_pExtPackMgr   Pointer to the extension pack manager.
- */
-HRESULT ExtPackFile::initWithFile(const char *a_pszFile, ExtPackManager *a_pExtPackMgr)
+ * @param   a_pVirtualBox   Pointer to the VirtualBox object.
+ */
+HRESULT ExtPackFile::initWithFile(const char *a_pszFile, ExtPackManager *a_pExtPackMgr, VirtualBox *a_pVirtualBox)
 {
     AutoInitSpan autoInitSpan(this);
@@ -190,5 +232,5 @@
      */
     m = new ExtPackFile::Data;
-    m->Desc.strName                 = NULL;
+    VBoxExtPackInitDesc(&m->Desc);
     RT_ZERO(m->ObjInfoDesc);
     m->fUsable                      = false;
@@ -198,4 +240,5 @@
     m->hOurManifest                 = NIL_RTMANIFEST;
     m->ptrExtPackMgr                = a_pExtPackMgr;
+    m->pVirtualBox                  = a_pVirtualBox;
 
     iprt::MiniString *pstrTarName = VBoxExtPackExtractNameFromTarballPath(a_pszFile);
@@ -589,5 +632,4 @@
     if (a_ppProgress)
         *a_ppProgress = NULL;
-    Utf8Str strDisplayInfo(a_bstrDisplayInfo);
 
     AutoCaller autoCaller(this);
@@ -596,5 +638,47 @@
     {
         if (m->fUsable)
-            hrc = m->ptrExtPackMgr->doInstall(this, RT_BOOL(a_fReplace), &strDisplayInfo, a_ppProgress);
+        {
+            PEXTPACKINSTALLJOB pJob = NULL;
+            try
+            {
+                pJob = new EXTPACKINSTALLJOB;
+                pJob->ptrExtPackFile    = this;
+                pJob->fReplace          = a_fReplace;
+                pJob->strDisplayInfo    = a_bstrDisplayInfo;
+                pJob->ptrExtPackMgr     = m->ptrExtPackMgr;
+                hrc = pJob->ptrProgress.createObject();
+                if (SUCCEEDED(hrc))
+                {
+                    Bstr bstrDescription = tr("Installing extension pack");
+                    hrc = pJob->ptrProgress->init(
+#ifndef VBOX_COM_INPROC
+                                                  m->pVirtualBox,
+#endif
+                                                  static_cast<IExtPackFile *>(this),
+                                                  bstrDescription.raw(),
+                                                  FALSE /*aCancelable*/,
+                                                  NULL /*aId*/);
+                }
+                if (SUCCEEDED(hrc))
+                {
+                    ComPtr<Progress> ptrProgress = pJob->ptrProgress;
+                    int vrc = RTThreadCreate(NULL /*phThread*/, ExtPackManager::doInstallThreadProc, pJob, 0,
+                                             RTTHREADTYPE_DEFAULT, 0 /*fFlags*/, "ExtPackInst");
+                    if (RT_SUCCESS(vrc))
+                    {
+                        pJob = NULL; /* the thread deletes it */
+                        ptrProgress.queryInterfaceTo(a_ppProgress);
+                    }
+                    else
+                        hrc = setError(VBOX_E_IPRT_ERROR, tr("RTThreadCreate failed with %Rrc"), vrc);
+                }
+            }
+            catch (std::bad_alloc)
+            {
+                hrc = E_OUTOFMEMORY;
+            }
+            if (pJob)
+                delete pJob;
+        }
         else
             hrc = setError(E_FAIL, "%s", m->strWhyUnusable.c_str());
@@ -663,4 +747,5 @@
      */
     m = new Data;
+    VBoxExtPackInitDesc(&m->Desc);
     m->Desc.strName                 = a_pszName;
     RT_ZERO(m->ObjInfoDesc);
@@ -1921,5 +2006,5 @@
     HRESULT hrc = NewExtPackFile.createObject();
     if (SUCCEEDED(hrc))
-        hrc = NewExtPackFile->initWithFile(strTarball.c_str(), this);
+        hrc = NewExtPackFile->initWithFile(strTarball.c_str(), this, m->pVirtualBox);
     if (SUCCEEDED(hrc))
         NewExtPackFile.queryInterfaceTo(a_ppExtPackFile);
@@ -1932,6 +2017,4 @@
 {
     CheckComArgNotNull(a_bstrName);
-    Utf8Str strName(a_bstrName);
-    Utf8Str strDisplayInfo(a_bstrDisplayInfo);
     if (a_ppProgress)
         *a_ppProgress = NULL;
@@ -1942,72 +2025,45 @@
     if (SUCCEEDED(hrc))
     {
-        AutoWriteLock autoLock(this COMMA_LOCKVAL_SRC_POS);
-
-        /*
-         * Refresh the data we have on the extension pack as it may be made
-         * stale by direct meddling or some other user.
-         */
-        ExtPack *pExtPack;
-        hrc = refreshExtPack(strName.c_str(), false /*a_fUnusableIsError*/, &pExtPack);
-        if (SUCCEEDED(hrc))
-        {
-            if (!pExtPack)
+        PEXTPACKUNINSTALLJOB pJob = NULL;
+        try
+        {
+            pJob = new EXTPACKUNINSTALLJOB;
+            pJob->ptrExtPackMgr     = this;
+            pJob->strName           = a_bstrName;
+            pJob->fForcedRemoval    = a_fForcedRemoval != FALSE;
+            pJob->strDisplayInfo    = a_bstrDisplayInfo;
+            hrc = pJob->ptrProgress.createObject();
+            if (SUCCEEDED(hrc))
             {
-                LogRel(("ExtPackManager: Extension pack '%s' is not installed, so nothing to uninstall.\n", strName.c_str()));
-                hrc = S_OK;             /* nothing to uninstall */
+                Bstr bstrDescription = tr("Uninstalling extension pack");
+                hrc = pJob->ptrProgress->init(
+#ifndef VBOX_COM_INPROC
+                                              m->pVirtualBox,
+#endif
+                                              static_cast<IExtPackManager *>(this),
+                                              bstrDescription.raw(),
+                                              FALSE /*aCancelable*/,
+                                              NULL /*aId*/);
             }
-            else
+            if (SUCCEEDED(hrc))
             {
-                /*
-                 * Call the uninstall hook and unload the main dll.
-                 */
-                hrc = pExtPack->callUninstallHookAndClose(m->pVirtualBox, a_fForcedRemoval != FALSE);
-                if (SUCCEEDED(hrc))
+                ComPtr<Progress> ptrProgress = pJob->ptrProgress;
+                int vrc = RTThreadCreate(NULL /*phThread*/, ExtPackManager::doUninstallThreadProc, pJob, 0,
+                                         RTTHREADTYPE_DEFAULT, 0 /*fFlags*/, "ExtPackUninst");
+                if (RT_SUCCESS(vrc))
                 {
-                    /*
-                     * Run the set-uid-to-root binary that performs the
-                     * uninstallation.  Then refresh the object.
-                     *
-                     * This refresh is theorically subject to races, but it's of
-                     * the don't-do-that variety.
-                     */
-                    const char *pszForcedOpt = a_fForcedRemoval ? "--forced" : NULL;
-                    hrc = runSetUidToRootHelper(&strDisplayInfo,
-                                                "uninstall",
-                                                "--base-dir", m->strBaseDir.c_str(),
-                                                "--name",     strName.c_str(),
-                                                pszForcedOpt, /* Last as it may be NULL. */
-                                                (const char *)NULL);
-                    if (SUCCEEDED(hrc))
-                    {
-                        hrc = refreshExtPack(strName.c_str(), false /*a_fUnusableIsError*/, &pExtPack);
-                        if (SUCCEEDED(hrc))
-                        {
-                            if (!pExtPack)
-                                LogRel(("ExtPackManager: Successfully uninstalled extension pack '%s'.\n", strName.c_str()));
-                            else
-                                hrc = setError(E_FAIL,
-                                               tr("Uninstall extension pack '%s' failed under mysterious circumstances"),
-                                               strName.c_str());
-                        }
-                    }
-                    else
-                    {
-                        ErrorInfoKeeper Eik;
-                        refreshExtPack(strName.c_str(), false /*a_fUnusableIsError*/, NULL);
-                    }
+                    pJob = NULL; /* the thread deletes it */
+                    ptrProgress.queryInterfaceTo(a_ppProgress);
                 }
+                else
+                    hrc = setError(VBOX_E_IPRT_ERROR, tr("RTThreadCreate failed with %Rrc"), vrc);
             }
         }
-
-        /*
-         * Do VirtualBoxReady callbacks now for any freshly installed
-         * extension pack (old ones will not be called).
-         */
-        if (m->enmContext == VBOXEXTPACKCTX_PER_USER_DAEMON)
-        {
-            autoLock.release();
-            callAllVirtualBoxReadyHooks();
-        }
+        catch (std::bad_alloc)
+        {
+            hrc = E_OUTOFMEMORY;
+        }
+        if (pJob)
+            delete pJob;
     }
 
@@ -2472,5 +2528,25 @@
 
 /**
+ * Thread wrapper around doInstall.
+ *
+ * @returns VINF_SUCCESS (ignored)
+ * @param   hThread             The thread handle (ignored).
+ * @param   pvJob               The job structure.
+ */
+/*static*/ DECLCALLBACK(int) ExtPackManager::doInstallThreadProc(RTTHREAD hThread, void *pvJob)
+{
+    PEXTPACKINSTALLJOB pJob = (PEXTPACKINSTALLJOB)pvJob;
+    HRESULT hrc = pJob->ptrExtPackMgr->doInstall(pJob->ptrExtPackFile, pJob->fReplace, &pJob->strDisplayInfo);
+    pJob->ptrProgress->notifyComplete(hrc);
+    delete pJob;
+
+    NOREF(hThread);
+    return VINF_SUCCESS;
+}
+
+/**
  * Worker for IExtPackFile::Install.
+ *
+ * Called on a worker thread via doInstallThreadProc.
  *
  * @returns COM status code.
@@ -2483,11 +2559,9 @@
  *                              be NULL.
  */
-HRESULT ExtPackManager::doInstall(ExtPackFile *a_pExtPackFile, bool a_fReplace, Utf8Str const *a_pstrDisplayInfo,
-                                  IProgress **a_ppProgress)
+HRESULT ExtPackManager::doInstall(ExtPackFile *a_pExtPackFile, bool a_fReplace, Utf8Str const *a_pstrDisplayInfo)
 {
     AssertReturn(m->enmContext == VBOXEXTPACKCTX_PER_USER_DAEMON, E_UNEXPECTED);
     iprt::MiniString const * const pStrName     = &a_pExtPackFile->m->Desc.strName;
     iprt::MiniString const * const pStrTarball  = &a_pExtPackFile->m->strExtPackFile;
-    NOREF(a_ppProgress); /** @todo implement progress object */
 
     AutoCaller autoCaller(this);
@@ -2580,4 +2654,115 @@
 }
 
+/**
+ * Thread wrapper around doUninstall.
+ *
+ * @returns VINF_SUCCESS (ignored)
+ * @param   hThread             The thread handle (ignored).
+ * @param   pvJob               The job structure.
+ */
+/*static*/ DECLCALLBACK(int) ExtPackManager::doUninstallThreadProc(RTTHREAD hThread, void *pvJob)
+{
+    PEXTPACKUNINSTALLJOB pJob = (PEXTPACKUNINSTALLJOB)pvJob;
+    HRESULT hrc = pJob->ptrExtPackMgr->doUninstall(&pJob->strName, pJob->fForcedRemoval, &pJob->strDisplayInfo);
+    pJob->ptrProgress->notifyComplete(hrc);
+    delete pJob;
+
+    NOREF(hThread);
+    return VINF_SUCCESS;
+}
+
+/**
+ * Worker for IExtPackManager::Uninstall.
+ *
+ * Called on a worker thread via doUninstallThreadProc.
+ *
+ * @returns COM status code.
+ * @param   a_pstrName          The name of the extension pack to uninstall.
+ * @param   a_fForcedRemoval    Whether to be skip and ignore certain bits of
+ *                              the extpack feedback.  To deal with misbehaving
+ *                              extension pack hooks.
+ * @param   a_pstrDisplayInfo   Host specific display information hacks.
+ */
+HRESULT ExtPackManager::doUninstall(Utf8Str const *a_pstrName, bool a_fForcedRemoval, Utf8Str const *a_pstrDisplayInfo)
+{
+    Assert(m->enmContext == VBOXEXTPACKCTX_PER_USER_DAEMON);
+
+    AutoCaller autoCaller(this);
+    HRESULT hrc = autoCaller.rc();
+    if (SUCCEEDED(hrc))
+    {
+        AutoWriteLock autoLock(this COMMA_LOCKVAL_SRC_POS);
+
+        /*
+         * Refresh the data we have on the extension pack as it may be made
+         * stale by direct meddling or some other user.
+         */
+        ExtPack *pExtPack;
+        hrc = refreshExtPack(a_pstrName->c_str(), false /*a_fUnusableIsError*/, &pExtPack);
+        if (SUCCEEDED(hrc))
+        {
+            if (!pExtPack)
+            {
+                LogRel(("ExtPackManager: Extension pack '%s' is not installed, so nothing to uninstall.\n", a_pstrName->c_str()));
+                hrc = S_OK;             /* nothing to uninstall */
+            }
+            else
+            {
+                /*
+                 * Call the uninstall hook and unload the main dll.
+                 */
+                hrc = pExtPack->callUninstallHookAndClose(m->pVirtualBox, a_fForcedRemoval);
+                if (SUCCEEDED(hrc))
+                {
+                    /*
+                     * Run the set-uid-to-root binary that performs the
+                     * uninstallation.  Then refresh the object.
+                     *
+                     * This refresh is theorically subject to races, but it's of
+                     * the don't-do-that variety.
+                     */
+                    const char *pszForcedOpt = a_fForcedRemoval ? "--forced" : NULL;
+                    hrc = runSetUidToRootHelper(a_pstrDisplayInfo,
+                                                "uninstall",
+                                                "--base-dir", m->strBaseDir.c_str(),
+                                                "--name",     a_pstrName->c_str(),
+                                                pszForcedOpt, /* Last as it may be NULL. */
+                                                (const char *)NULL);
+                    if (SUCCEEDED(hrc))
+                    {
+                        hrc = refreshExtPack(a_pstrName->c_str(), false /*a_fUnusableIsError*/, &pExtPack);
+                        if (SUCCEEDED(hrc))
+                        {
+                            if (!pExtPack)
+                                LogRel(("ExtPackManager: Successfully uninstalled extension pack '%s'.\n", a_pstrName->c_str()));
+                            else
+                                hrc = setError(E_FAIL,
+                                               tr("Uninstall extension pack '%s' failed under mysterious circumstances"),
+                                               a_pstrName->c_str());
+                        }
+                    }
+                    else
+                    {
+                        ErrorInfoKeeper Eik;
+                        refreshExtPack(a_pstrName->c_str(), false /*a_fUnusableIsError*/, NULL);
+                    }
+                }
+            }
+        }
+
+        /*
+         * Do VirtualBoxReady callbacks now for any freshly installed
+         * extension pack (old ones will not be called).
+         */
+        if (m->enmContext == VBOXEXTPACKCTX_PER_USER_DAEMON)
+        {
+            autoLock.release();
+            callAllVirtualBoxReadyHooks();
+        }
+    }
+
+    return hrc;
+}
+
 
 /**
Index: /trunk/src/VBox/Main/src-all/ExtPackUtil.cpp
===================================================================
--- /trunk/src/VBox/Main/src-all/ExtPackUtil.cpp	(revision 35522)
+++ /trunk/src/VBox/Main/src-all/ExtPackUtil.cpp	(revision 35523)
@@ -77,4 +77,16 @@
     a_pExtPackDesc->fShowLicense = false;
 }
+
+/**
+ * Initializes an extension pack descriptor so that it's safe to call free on
+ * it whatever happens later on.
+ *
+ * @param   a_pExtPackDesc  The descirptor to initialize.
+ */
+void VBoxExtPackInitDesc(PVBOXEXTPACKDESC a_pExtPackDesc)
+{
+    vboxExtPackClearDesc(a_pExtPackDesc);
+}
+
 
 /**
