Index: trunk/src/VBox/Main/include/ConsoleImpl.h
===================================================================
--- trunk/src/VBox/Main/include/ConsoleImpl.h	(revision 48311)
+++ trunk/src/VBox/Main/include/ConsoleImpl.h	(revision 48313)
@@ -221,4 +221,5 @@
     HRESULT onBandwidthGroupChange(IBandwidthGroup *aBandwidthGroup);
     HRESULT onStorageDeviceChange(IMediumAttachment *aMediumAttachment, BOOL aRemove, BOOL aSilent);
+
     HRESULT getGuestProperty(IN_BSTR aKey, BSTR *aValue, LONG64 *aTimestamp, BSTR *aFlags);
     HRESULT setGuestProperty(IN_BSTR aKey, IN_BSTR aValue, IN_BSTR aFlags);
@@ -231,4 +232,5 @@
                               ULONG aSourceIdx, ULONG aTargetIdx,
                               IProgress *aProgress);
+    int hgcmLoadService(const char *pszServiceLibrary, const char *pszServiceName);
     VMMDev *getVMMDev() { return m_pVMMDev; }
     AudioSniffer *getAudioSniffer() { return mAudioSniffer; }
Index: trunk/src/VBox/Main/include/ExtPackManagerImpl.h
===================================================================
--- trunk/src/VBox/Main/include/ExtPackManagerImpl.h	(revision 48311)
+++ trunk/src/VBox/Main/include/ExtPackManagerImpl.h	(revision 48313)
@@ -5,5 +5,5 @@
 
 /*
- * Copyright (C) 2010-2012 Oracle Corporation
+ * Copyright (C) 2010-2013 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -168,4 +168,5 @@
     static DECLCALLBACK(int)    hlpGetFilePath(PCVBOXEXTPACKHLP pHlp, const char *pszFilename, char *pszPath, size_t cbPath);
     static DECLCALLBACK(VBOXEXTPACKCTX) hlpGetContext(PCVBOXEXTPACKHLP pHlp);
+    static DECLCALLBACK(int)    hlpLoadHGCMService(PCVBOXEXTPACKHLP pHlp, VBOXEXTPACK_IF_CS(IConsole) *pConsole, const char *pszServiceLibrary, const char *pszServiceName);
     static DECLCALLBACK(int)    hlpReservedN(PCVBOXEXTPACKHLP pHlp);
     /** @}  */
Index: trunk/src/VBox/Main/src-all/ExtPackManagerImpl.cpp
===================================================================
--- trunk/src/VBox/Main/src-all/ExtPackManagerImpl.cpp	(revision 48311)
+++ trunk/src/VBox/Main/src-all/ExtPackManagerImpl.cpp	(revision 48313)
@@ -45,7 +45,8 @@
 #include "Global.h"
 #include "ProgressImpl.h"
-#include "SystemPropertiesImpl.h"
-#if !defined(VBOX_COM_INPROC)
-#include "VirtualBoxImpl.h"
+#if defined(VBOX_COM_INPROC)
+# include "ConsoleImpl.h"
+#else
+# include "VirtualBoxImpl.h"
 #endif
 
@@ -758,4 +759,5 @@
         /* pfnGetFilePath       = */ ExtPack::hlpGetFilePath,
         /* pfnGetContext        = */ ExtPack::hlpGetContext,
+        /* pfnLoadHGCMService   = */ ExtPack::hlpLoadHGCMService,
         /* pfnReserved1         = */ ExtPack::hlpReservedN,
         /* pfnReserved2         = */ ExtPack::hlpReservedN,
@@ -766,5 +768,4 @@
         /* pfnReserved7         = */ ExtPack::hlpReservedN,
         /* pfnReserved8         = */ ExtPack::hlpReservedN,
-        /* pfnReserved9         = */ ExtPack::hlpReservedN,
         /* u32EndMarker         = */ VBOXEXTPACKHLP_VERSION
     };
@@ -1578,4 +1579,29 @@
 
     return pThis->m->enmContext;
+}
+
+/*static*/ DECLCALLBACK(int)
+ExtPack::hlpLoadHGCMService(PCVBOXEXTPACKHLP pHlp, VBOXEXTPACK_IF_CS(IConsole) *pConsole,
+                            const char *pszServiceLibrary, const char *pszServiceName)
+{
+#ifdef VBOX_COM_INPROC
+    /*
+     * Validate the input and get our bearings.
+     */
+    AssertPtrReturn(pszServiceLibrary, VERR_INVALID_POINTER);
+    AssertPtrReturn(pszServiceName, VERR_INVALID_POINTER);
+
+    AssertPtrReturn(pHlp, VERR_INVALID_POINTER);
+    AssertReturn(pHlp->u32Version == VBOXEXTPACKHLP_VERSION, VERR_INVALID_POINTER);
+    ExtPack::Data *m = RT_FROM_CPP_MEMBER(pHlp, Data, Hlp);
+    AssertPtrReturn(m, VERR_INVALID_POINTER);
+    ExtPack *pThis = m->pThis;
+    AssertPtrReturn(pThis, VERR_INVALID_POINTER);
+    AssertPtrReturn(pConsole, VERR_INVALID_POINTER);
+
+    Console *pCon = (Console *)pConsole;
+    return pCon->hgcmLoadService(pszServiceLibrary, pszServiceName);
+#endif
+    return VERR_INVALID_STATE;
 }
 
Index: trunk/src/VBox/Main/src-client/ConsoleImpl.cpp
===================================================================
--- trunk/src/VBox/Main/src-client/ConsoleImpl.cpp	(revision 48311)
+++ trunk/src/VBox/Main/src-client/ConsoleImpl.cpp	(revision 48313)
@@ -5748,4 +5748,21 @@
 }
 
+
+/**
+ * Load an HGCM service.
+ *
+ * Main purpose of this method is to allow extension packs to load HGCM
+ * service modules, which they can't, because the HGCM functionality lives
+ * in module VBoxC (and ConsoleImpl.cpp is part of it and thus can call it).
+ * Extension modules must not link directly against VBoxC, (XP)COM is
+ * handling this.
+ */
+int Console::hgcmLoadService(const char *pszServiceLibrary, const char *pszServiceName)
+{
+    /* Everyone seems to delegate all HGCM calls to VMMDev, so stick to this
+     * convention. Adds one level of indirection for no obvious reason. */
+    AssertPtrReturn(m_pVMMDev, VERR_INVALID_STATE);
+    return m_pVMMDev->hgcmLoadService(pszServiceLibrary, pszServiceName);
+}
 
 /**
