Index: trunk/src/VBox/Main/include/ExtPackManagerImpl.h
===================================================================
--- trunk/src/VBox/Main/include/ExtPackManagerImpl.h	(revision 68811)
+++ trunk/src/VBox/Main/include/ExtPackManagerImpl.h	(revision 68828)
@@ -5,5 +5,5 @@
 
 /*
- * Copyright (C) 2010-2016 Oracle Corporation
+ * Copyright (C) 2010-2017 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -31,5 +31,5 @@
 
 
-#if !defined(VBOX_COM_INPROC)
+#ifndef VBOX_COM_INPROC
 /**
  * An extension pack file.
@@ -87,5 +87,5 @@
     friend class ExtPackInstallTask;
 };
-#endif
+#endif /* !VBOX_COM_INPROC */
 
 
@@ -110,12 +110,20 @@
     /** @name Internal interfaces used by ExtPackManager.
      * @{ */
+#ifndef VBOX_COM_INPROC
     bool        i_callInstalledHook(IVirtualBox *a_pVirtualBox, AutoWriteLock *a_pLock, PRTERRINFO pErrInfo);
     HRESULT     i_callUninstallHookAndClose(IVirtualBox *a_pVirtualBox, bool a_fForcedRemoval);
     bool        i_callVirtualBoxReadyHook(IVirtualBox *a_pVirtualBox, AutoWriteLock *a_pLock);
+#endif
+#ifdef VBOX_COM_INPROC
     bool        i_callConsoleReadyHook(IConsole *a_pConsole, AutoWriteLock *a_pLock);
+#endif
+#ifndef VBOX_COM_INPROC
     bool        i_callVmCreatedHook(IVirtualBox *a_pVirtualBox, IMachine *a_pMachine, AutoWriteLock *a_pLock);
+#endif
+#ifdef VBOX_COM_INPROC
     bool        i_callVmConfigureVmmHook(IConsole *a_pConsole, PVM a_pVM, AutoWriteLock *a_pLock, int *a_pvrc);
     bool        i_callVmPowerOnHook(IConsole *a_pConsole, PVM a_pVM, AutoWriteLock *a_pLock, int *a_pvrc);
     bool        i_callVmPowerOffHook(IConsole *a_pConsole, PVM a_pVM, AutoWriteLock *a_pLock);
+#endif
     HRESULT     i_checkVrde(void);
     HRESULT     i_getVrdpLibraryName(Utf8Str *a_pstrVrdeLibrary);
@@ -197,14 +205,20 @@
     /** @name Internal interfaces used by other Main classes.
      * @{ */
-#if !defined(VBOX_COM_INPROC)
+#ifndef VBOX_COM_INPROC
     HRESULT     i_doInstall(ExtPackFile *a_pExtPackFile, bool a_fReplace, Utf8Str const *a_pstrDisplayInfo);
     HRESULT     i_doUninstall(const Utf8Str *a_pstrName, bool a_fForcedRemoval, const Utf8Str *a_pstrDisplayInfo);
-#endif
     void        i_callAllVirtualBoxReadyHooks(void);
+#endif
+#ifdef VBOX_COM_INPROC
     void        i_callAllConsoleReadyHooks(IConsole *a_pConsole);
+#endif
+#ifndef VBOX_COM_INPROC
     void        i_callAllVmCreatedHooks(IMachine *a_pMachine);
+#endif
+#ifdef VBOX_COM_INPROC
     int         i_callAllVmConfigureVmmHooks(IConsole *a_pConsole, PVM a_pVM);
     int         i_callAllVmPowerOnHooks(IConsole *a_pConsole, PVM a_pVM);
     void        i_callAllVmPowerOffHooks(IConsole *a_pConsole, PVM a_pVM);
+#endif
     HRESULT     i_checkVrdeExtPack(Utf8Str const *a_pstrExtPack);
     int         i_getVrdeLibraryPathForExtPack(Utf8Str const *a_pstrExtPack, Utf8Str *a_pstrVrdeLibrary);
Index: trunk/src/VBox/Main/include/ExtPackUtil.h
===================================================================
--- trunk/src/VBox/Main/include/ExtPackUtil.h	(revision 68811)
+++ trunk/src/VBox/Main/include/ExtPackUtil.h	(revision 68828)
@@ -5,5 +5,5 @@
 
 /*
- * Copyright (C) 2010-2016 Oracle Corporation
+ * Copyright (C) 2010-2017 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -100,4 +100,6 @@
     /** The name of the main module. */
     RTCString               strMainModule;
+    /** The name of the main VM module, empty if none. */
+    RTCString               strMainVMModule;
     /** The name of the VRDE module, empty if none. */
     RTCString               strVrdeModule;
Index: trunk/src/VBox/Main/src-all/ExtPackManagerImpl.cpp
===================================================================
--- trunk/src/VBox/Main/src-all/ExtPackManagerImpl.cpp	(revision 68811)
+++ trunk/src/VBox/Main/src-all/ExtPackManagerImpl.cpp	(revision 68828)
@@ -46,5 +46,5 @@
 #include "Global.h"
 #include "ProgressImpl.h"
-#if defined(VBOX_COM_INPROC)
+#ifdef VBOX_COM_INPROC
 # include "ConsoleImpl.h"
 #else
@@ -85,5 +85,5 @@
 };
 
-#if !defined(VBOX_COM_INPROC)
+#ifndef VBOX_COM_INPROC
 /**
  * Private extension pack data.
@@ -132,6 +132,11 @@
     /** Pointer back to the extension pack object (for Hlp methods). */
     ExtPack            *pThis;
-    /** The extension pack registration structure. */
+#ifndef VBOX_COM_INPROC
+    /** The extension pack main registration structure. */
     PCVBOXEXTPACKREG    pReg;
+#else
+    /** The extension pack main VM registration structure. */
+    PCVBOXEXTPACKVMREG  pReg;
+#endif
     /** The current context. */
     VBOXEXTPACKCTX      enmContext;
@@ -157,5 +162,5 @@
     /** The list of installed extension packs. */
     ExtPackList         llInstalledExtPacks;
-#if !defined(VBOX_COM_INPROC)
+#ifndef VBOX_COM_INPROC
     /** Pointer to the VirtualBox object, our parent. */
     VirtualBox         *pVirtualBox;
@@ -163,13 +168,9 @@
     /** The current context. */
     VBOXEXTPACKCTX      enmContext;
-#if !defined(RT_OS_WINDOWS) && !defined(RT_OS_DARWIN)
-    /** File handle for the VBoxVMM libary which we slurp because ExtPacks depend on it. */
-    RTLDRMOD            hVBoxVMM;
-#endif
 
     RTMEMEF_NEW_AND_DELETE_OPERATORS();
 };
 
-#if !defined(VBOX_COM_INPROC)
+#ifndef VBOX_COM_INPROC
 
 /**
@@ -821,4 +822,5 @@
 
 
+#ifndef VBOX_COM_INPROC
 /**
  * Calls the installed hook.
@@ -895,4 +897,5 @@
     if (    m != NULL
         &&  m->fUsable
+        &&  m->hMainMod != NIL_RTLDRMOD
         && !m->fMadeReadyCall)
     {
@@ -909,5 +912,7 @@
     return false;
 }
-
+#endif /* !VBOX_COM_INPROC */
+
+#ifdef VBOX_COM_INPROC
 /**
  * Calls the pfnConsoleReady hook.
@@ -921,4 +926,5 @@
     if (    m != NULL
         &&  m->fUsable
+        &&  m->hMainMod != NIL_RTLDRMOD
         && !m->fMadeReadyCall)
     {
@@ -935,5 +941,7 @@
     return false;
 }
-
+#endif /* VBOX_COM_INPROC */
+
+#ifndef VBOX_COM_INPROC
 /**
  * Calls the pfnVMCreate hook.
@@ -947,4 +955,5 @@
 {
     if (   m != NULL
+        && m->hMainMod != NIL_RTLDRMOD
         && m->fUsable)
     {
@@ -960,5 +969,7 @@
     return false;
 }
-
+#endif /* !VBOX_COM_INPROC */
+
+#ifdef VBOX_COM_INPROC
 /**
  * Calls the pfnVMConfigureVMM hook.
@@ -976,4 +987,5 @@
     *a_pvrc = VINF_SUCCESS;
     if (   m != NULL
+        && m->hMainMod != NIL_RTLDRMOD
         && m->fUsable)
     {
@@ -1008,4 +1020,5 @@
     *a_pvrc = VINF_SUCCESS;
     if (   m != NULL
+        && m->hMainMod != NIL_RTLDRMOD
         && m->fUsable)
     {
@@ -1036,4 +1049,5 @@
 {
     if (   m != NULL
+        && m->hMainMod != NIL_RTLDRMOD
         && m->fUsable)
     {
@@ -1049,4 +1063,5 @@
     return false;
 }
+#endif /* !VBOX_COM_INPROC */
 
 /**
@@ -1285,9 +1300,23 @@
      * Load the main DLL and call the predefined entry point.
      */
+#ifndef VBOX_COM_INPROC
+    const char *pszMainModule = m->Desc.strMainModule.c_str();
+#else
+    const char *pszMainModule = m->Desc.strMainVMModule.c_str();
+    if (m->Desc.strMainVMModule.isEmpty())
+    {
+        /*
+         * We're good! The main module for VM processes is optional.
+         */
+        m->fUsable = true;
+        m->strWhyUnusable.setNull();
+        return;
+    }
+#endif
     bool fIsNative;
-    if (!i_findModule(m->Desc.strMainModule.c_str(), NULL /* default extension */, VBOXEXTPACKMODKIND_R3,
+    if (!i_findModule(pszMainModule, NULL /* default extension */, VBOXEXTPACKMODKIND_R3,
                       &m->strMainModPath, &fIsNative, &m->ObjInfoMainMod))
     {
-        m->strWhyUnusable.printf(tr("Failed to locate the main module ('%s')"), m->Desc.strMainModule.c_str());
+        m->strWhyUnusable.printf(tr("Failed to locate the main module ('%s')"), pszMainModule);
         return;
     }
@@ -1320,6 +1349,14 @@
      * Resolve the predefined entry point.
      */
+#ifndef VBOX_COM_INPROC
+    const char *pszMainEntryPoint = VBOX_EXTPACK_MAIN_MOD_ENTRY_POINT;
     PFNVBOXEXTPACKREGISTER pfnRegistration;
-    vrc = RTLdrGetSymbol(m->hMainMod, VBOX_EXTPACK_MAIN_MOD_ENTRY_POINT, (void **)&pfnRegistration);
+    uint32_t uVersion = VBOXEXTPACKREG_VERSION;
+#else
+    const char *pszMainEntryPoint = VBOX_EXTPACK_MAIN_VM_MOD_ENTRY_POINT;
+    PFNVBOXEXTPACKVMREGISTER pfnRegistration;
+    uint32_t uVersion = VBOXEXTPACKVMREG_VERSION;
+#endif
+    vrc = RTLdrGetSymbol(m->hMainMod, pszMainEntryPoint, (void **)&pfnRegistration);
     if (RT_SUCCESS(vrc))
     {
@@ -1330,13 +1367,26 @@
             && VALID_PTR(m->pReg))
         {
-            if (   VBOXEXTPACK_IS_MAJOR_VER_EQUAL(m->pReg->u32Version, VBOXEXTPACKREG_VERSION)
+            if (   VBOXEXTPACK_IS_MAJOR_VER_EQUAL(m->pReg->u32Version, uVersion)
                 && m->pReg->u32EndMarker == m->pReg->u32Version)
             {
+#ifndef VBOX_COM_INPROC
                 if (   (!m->pReg->pfnInstalled       || RT_VALID_PTR(m->pReg->pfnInstalled))
                     && (!m->pReg->pfnUninstall       || RT_VALID_PTR(m->pReg->pfnUninstall))
                     && (!m->pReg->pfnVirtualBoxReady || RT_VALID_PTR(m->pReg->pfnVirtualBoxReady))
-                    && (!m->pReg->pfnConsoleReady    || RT_VALID_PTR(m->pReg->pfnConsoleReady))
                     && (!m->pReg->pfnUnload          || RT_VALID_PTR(m->pReg->pfnUnload))
                     && (!m->pReg->pfnVMCreated       || RT_VALID_PTR(m->pReg->pfnVMCreated))
+                    && (!m->pReg->pfnQueryObject     || RT_VALID_PTR(m->pReg->pfnQueryObject))
+                    )
+                {
+                    /*
+                     * We're good!
+                     */
+                    m->fUsable = true;
+                    m->strWhyUnusable.setNull();
+                    return;
+                }
+#else
+                if (   (!m->pReg->pfnConsoleReady    || RT_VALID_PTR(m->pReg->pfnConsoleReady))
+                    && (!m->pReg->pfnUnload          || RT_VALID_PTR(m->pReg->pfnUnload))
                     && (!m->pReg->pfnVMConfigureVMM  || RT_VALID_PTR(m->pReg->pfnVMConfigureVMM))
                     && (!m->pReg->pfnVMPowerOn       || RT_VALID_PTR(m->pReg->pfnVMPowerOn))
@@ -1352,6 +1402,7 @@
                     return;
                 }
-
-                m->strWhyUnusable = tr("The registration structure contains on or more invalid function pointers");
+#endif
+
+                m->strWhyUnusable = tr("The registration structure contains one or more invalid function pointers");
             }
             else
@@ -1361,10 +1412,10 @@
         else
             m->strWhyUnusable.printf(tr("%s returned %Rrc, pReg=%p ErrInfo='%s'"),
-                                     VBOX_EXTPACK_MAIN_MOD_ENTRY_POINT, vrc, m->pReg, ErrInfo.Core.pszMsg);
+                                     pszMainEntryPoint, vrc, m->pReg, ErrInfo.Core.pszMsg);
         m->pReg = NULL;
     }
     else
         m->strWhyUnusable.printf(tr("Failed to resolve exported symbol '%s' in the main module: %Rrc"),
-                                 VBOX_EXTPACK_MAIN_MOD_ENTRY_POINT, vrc);
+                                 pszMainEntryPoint, vrc);
 
     RTLdrClose(m->hMainMod);
@@ -1904,17 +1955,4 @@
 #else
     RT_NOREF_PV(a_pVirtualBox);
-#endif
-
-    /*
-     * Slurp in VBoxVMM which is used by VBoxPuelMain.
-     */
-#if !defined(RT_OS_WINDOWS) && !defined(RT_OS_DARWIN)
-    if (a_enmContext == VBOXEXTPACKCTX_PER_USER_DAEMON)
-    {
-        int vrc = SUPR3HardenedLdrLoadAppPriv("VBoxVMM", &m->hVBoxVMM, RTLDRLOAD_FLAGS_GLOBAL, NULL);
-        if (RT_FAILURE(vrc))
-            m->hVBoxVMM = NIL_RTLDRMOD;
-        /* cleanup in ::uninit()? */
-    }
 #endif
 
@@ -2043,5 +2081,5 @@
     AssertReturn(m->enmContext == VBOXEXTPACKCTX_PER_USER_DAEMON, E_UNEXPECTED);
 
-#if !defined(VBOX_COM_INPROC)
+#ifndef VBOX_COM_INPROC
     /* The API can optionally take a ::SHA-256=<hex-digest> attribute at the
        end of the file name.  This is just a temporary measure for
@@ -2077,5 +2115,5 @@
     Assert(m->enmContext == VBOXEXTPACKCTX_PER_USER_DAEMON);
 
-#if !defined(VBOX_COM_INPROC)
+#ifndef VBOX_COM_INPROC
 
     HRESULT hrc;
@@ -2436,5 +2474,5 @@
 }
 
-#if !defined(VBOX_COM_INPROC)
+#ifndef VBOX_COM_INPROC
 
 /**
@@ -2859,4 +2897,5 @@
 #endif /* !VBOX_COM_INPROC */
 
+#ifdef VBOX_COM_INPROC
 /**
  * Calls the pfnConsoleReady hook for all working extension packs.
@@ -2884,6 +2923,7 @@
     }
 }
-
-#if !defined(VBOX_COM_INPROC)
+#endif
+
+#ifndef VBOX_COM_INPROC
 /**
  * Calls the pfnVMCreated hook for all working extension packs.
@@ -2906,4 +2946,5 @@
 #endif
 
+#ifdef VBOX_COM_INPROC
 /**
  * Calls the pfnVMConfigureVMM hook for all working extension packs.
@@ -2983,4 +3024,5 @@
         (*it)->i_callVmPowerOffHook(a_pConsole, a_pVM, &autoLock);
 }
+#endif
 
 
Index: trunk/src/VBox/Main/src-all/ExtPackUtil.cpp
===================================================================
--- trunk/src/VBox/Main/src-all/ExtPackUtil.cpp	(revision 68811)
+++ trunk/src/VBox/Main/src-all/ExtPackUtil.cpp	(revision 68828)
@@ -5,5 +5,5 @@
 
 /*
- * Copyright (C) 2010-2016 Oracle Corporation
+ * Copyright (C) 2010-2017 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -74,4 +74,5 @@
     a_pExtPackDesc->uRevision = 0;
     a_pExtPackDesc->strMainModule.setNull();
+    a_pExtPackDesc->strMainVMModule.setNull();
     a_pExtPackDesc->strVrdeModule.setNull();
     a_pExtPackDesc->cPlugIns = 0;
@@ -164,4 +165,19 @@
 
     /*
+     * The main VM module, optional.
+     * Accept both none and empty as tokens of no main VM module.
+     */
+    const char *pszMainVMModule = NULL;
+    const xml::ElementNode *pMainVMModuleElm = pVBoxExtPackElm->findChildElement("MainVMModule");
+    if (pMainVMModuleElm)
+    {
+        pszMainVMModule = pMainVMModuleElm->getValue();
+        if (!pszMainVMModule || *pszMainVMModule == '\0')
+            pszMainVMModule = NULL;
+        else if (!VBoxExtPackIsValidModuleString(pszMainVMModule))
+            return &(new RTCString("Invalid main VM module string: "))->append(pszMainVMModule);
+    }
+
+    /*
      * The VRDE module, optional.
      * Accept both none and empty as tokens of no VRDE module.
@@ -205,4 +221,5 @@
     a_pExtPackDesc->uRevision       = uRevision;
     a_pExtPackDesc->strMainModule   = pszMainModule;
+    a_pExtPackDesc->strMainVMModule = pszMainVMModule;
     a_pExtPackDesc->strVrdeModule   = pszVrdeModule;
     a_pExtPackDesc->cPlugIns        = cPlugIns;
@@ -362,4 +379,5 @@
     a_pExtPackDesc->uRevision = 0;
     a_pExtPackDesc->strMainModule.setNull();
+    a_pExtPackDesc->strMainVMModule.setNull();
     a_pExtPackDesc->strVrdeModule.setNull();
     a_pExtPackDesc->cPlugIns = 0;
Index: trunk/src/VBox/Main/src-client/ConsoleImpl.cpp
===================================================================
--- trunk/src/VBox/Main/src-client/ConsoleImpl.cpp	(revision 68811)
+++ trunk/src/VBox/Main/src-client/ConsoleImpl.cpp	(revision 68828)
@@ -825,4 +825,8 @@
     // we don't perform uninit() as it's possible that some pending event refers to this source
     unconst(mEventSource).setNull();
+
+#ifdef VBOX_WITH_EXTPACK
+    unconst(mptrExtPackManager).setNull();
+#endif
 
     LogFlowThisFuncLeave();
