summaryrefslogtreecommitdiffstats
path: root/src/VBox/Main/src-client/win/dllmain.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/VBox/Main/src-client/win/dllmain.cpp')
-rw-r--r--src/VBox/Main/src-client/win/dllmain.cpp176
1 files changed, 176 insertions, 0 deletions
diff --git a/src/VBox/Main/src-client/win/dllmain.cpp b/src/VBox/Main/src-client/win/dllmain.cpp
new file mode 100644
index 00000000..3c681291
--- /dev/null
+++ b/src/VBox/Main/src-client/win/dllmain.cpp
@@ -0,0 +1,176 @@
+/* $Id: dllmain.cpp $ */
+/** @file
+ * VBoxC - COM DLL exports and DLL init/term.
+ */
+
+/*
+ * Copyright (C) 2006-2022 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+
+/*********************************************************************************************************************************
+* Header Files *
+*********************************************************************************************************************************/
+#include "VBox/com/defs.h"
+
+#include <SessionImpl.h>
+#include <VirtualBoxClientImpl.h>
+
+#include <iprt/initterm.h>
+
+
+/*********************************************************************************************************************************
+* Global Variables *
+*********************************************************************************************************************************/
+static ATL::CComModule *g_pAtlComModule;
+
+BEGIN_OBJECT_MAP(ObjectMap)
+ OBJECT_ENTRY(CLSID_Session, Session)
+ OBJECT_ENTRY(CLSID_VirtualBoxClient, VirtualBoxClient)
+END_OBJECT_MAP()
+
+
+/////////////////////////////////////////////////////////////////////////////
+// DLL Entry Point
+
+extern "C"
+BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
+{
+ if (dwReason == DLL_PROCESS_ATTACH)
+ {
+ // idempotent, so doesn't harm, and needed for COM embedding scenario
+ RTR3InitDll(RTR3INIT_FLAGS_UNOBTRUSIVE);
+
+ g_pAtlComModule = new(ATL::CComModule);
+ if (!g_pAtlComModule)
+ return FALSE;
+
+ g_pAtlComModule->Init(ObjectMap, hInstance, &LIBID_VirtualBox);
+ DisableThreadLibraryCalls(hInstance);
+ }
+ else if (dwReason == DLL_PROCESS_DETACH)
+ {
+ if (g_pAtlComModule)
+ {
+ g_pAtlComModule->Term();
+ delete g_pAtlComModule;
+ g_pAtlComModule = NULL;
+ }
+ }
+ return TRUE;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Used to determine whether the DLL can be unloaded by OLE
+
+STDAPI DllCanUnloadNow(void)
+{
+ AssertReturn(g_pAtlComModule, S_OK);
+ LONG const cLocks = g_pAtlComModule->GetLockCount();
+ Assert(cLocks >= VirtualBoxClient::s_cUnnecessaryAtlModuleLocks);
+ return cLocks <= VirtualBoxClient::s_cUnnecessaryAtlModuleLocks ? S_OK : S_FALSE;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Returns a class factory to create an object of the requested type
+
+STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
+{
+ AssertReturn(g_pAtlComModule, E_UNEXPECTED);
+ return g_pAtlComModule->GetClassObject(rclsid, riid, ppv);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// DllRegisterServer - Adds entries to the system registry
+
+STDAPI DllRegisterServer(void)
+{
+#ifndef VBOX_WITH_MIDL_PROXY_STUB
+ // registers object, typelib and all interfaces in typelib
+ AssertReturn(g_pAtlComModule, E_UNEXPECTED);
+ return g_pAtlComModule->RegisterServer(TRUE);
+#else
+ return S_OK; /* VBoxProxyStub does all the work, no need to duplicate it here. */
+#endif
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// DllUnregisterServer - Removes entries from the system registry
+
+STDAPI DllUnregisterServer(void)
+{
+#ifndef VBOX_WITH_MIDL_PROXY_STUB
+ AssertReturn(g_pAtlComModule, E_UNEXPECTED);
+ HRESULT hrc = g_pAtlComModule->UnregisterServer(TRUE);
+ return hrc;
+#else
+ return S_OK; /* VBoxProxyStub does all the work, no need to duplicate it here. */
+#endif
+}
+
+
+#ifdef RT_OS_WINDOWS
+/*
+ * HACK ALERT! Really ugly trick to make the VirtualBoxClient object go away
+ * when nobody uses it anymore. This is to prevent its uninit()
+ * method from accessing IVirtualBox and similar proxy stubs after
+ * COM has been officially shut down.
+ *
+ * It is simply TOO LATE to destroy the client object from DllMain/detach!
+ *
+ * This hack ASSUMES ObjectMap order.
+ * This hack is subject to a re-instantiation race.
+ */
+ULONG VirtualBoxClient::InternalRelease()
+{
+ ULONG cRefs = VirtualBoxClientWrap::InternalRelease();
+# ifdef DEBUG_bird
+ char szMsg[64];
+ RTStrPrintf(szMsg, sizeof(szMsg), "VirtualBoxClient: cRefs=%d\n", cRefs);
+ OutputDebugStringA(szMsg);
+# endif
+# if 1 /* enable ugly hack */
+ if (cRefs == 1)
+ {
+ /* Make the factory to drop its reference. */
+ if (ObjectMap[1].pCF)
+ {
+ InternalAddRef();
+
+ CMyComClassFactorySingleton<VirtualBoxClient> *pFactory;
+ pFactory = dynamic_cast<CMyComClassFactorySingleton<VirtualBoxClient> *>(ObjectMap[1].pCF);
+ Assert(pFactory);
+ if (pFactory)
+ {
+ IUnknown *pUnknown = pFactory->m_spObj;
+ pFactory->m_spObj = NULL;
+ if (pUnknown)
+ pUnknown->Release();
+ }
+
+ cRefs = VirtualBoxClientWrap::InternalRelease();
+ }
+ }
+# endif
+ return cRefs;
+}
+#endif
+