summaryrefslogtreecommitdiff
path: root/src/VBox/Main/src-client/win/dllmain.cpp
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@baserock.org>2014-03-26 19:21:20 +0000
committer <>2014-05-08 15:03:54 +0000
commitfb123f93f9f5ce42c8e5785d2f8e0edaf951740e (patch)
treec2103d76aec5f1f10892cd1d3a38e24f665ae5db /src/VBox/Main/src-client/win/dllmain.cpp
parent58ed4748338f9466599adfc8a9171280ed99e23f (diff)
downloadVirtualBox-master.tar.gz
Imported from /home/lorry/working-area/delta_VirtualBox/VirtualBox-4.3.10.tar.bz2.HEADVirtualBox-4.3.10master
Diffstat (limited to 'src/VBox/Main/src-client/win/dllmain.cpp')
-rw-r--r--src/VBox/Main/src-client/win/dllmain.cpp327
1 files changed, 321 insertions, 6 deletions
diff --git a/src/VBox/Main/src-client/win/dllmain.cpp b/src/VBox/Main/src-client/win/dllmain.cpp
index db1181cb..2410e97c 100644
--- a/src/VBox/Main/src-client/win/dllmain.cpp
+++ b/src/VBox/Main/src-client/win/dllmain.cpp
@@ -1,11 +1,10 @@
+/* $Id: dllmain.cpp $ */
/** @file
- *
- * DLLMAIN - COM DLL exports
- *
+ * VBoxC - COM DLL exports and DLL init/term.
*/
/*
- * Copyright (C) 2006-2007 Oracle Corporation
+ * Copyright (C) 2006-2013 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -16,6 +15,10 @@
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*/
+
+/*******************************************************************************
+* Header Files *
+*******************************************************************************/
#include "VBox/com/defs.h"
#include <SessionImpl.h>
@@ -25,7 +28,13 @@
#include <atlcom.h>
#include <iprt/initterm.h>
+#include <iprt/assert.h>
+#include <iprt/string.h>
+
+/*******************************************************************************
+* Global Variables *
+*******************************************************************************/
CComModule _Module;
BEGIN_OBJECT_MAP(ObjectMap)
@@ -33,6 +42,46 @@ BEGIN_OBJECT_MAP(ObjectMap)
OBJECT_ENTRY(CLSID_VirtualBoxClient, VirtualBoxClient)
END_OBJECT_MAP()
+
+/** @def WITH_MANUAL_CLEANUP
+ * Manually clean up the registry. */
+#if defined(DEBUG) && !defined(VBOX_IN_32_ON_64_MAIN_API)
+//# define WITH_MANUAL_CLEANUP
+#endif
+
+
+#ifdef WITH_MANUAL_CLEANUP
+/** Type library GUIDs to clean up manually. */
+static const char * const g_apszTypelibGuids[] =
+{
+ "{46137EEC-703B-4FE5-AFD4-7C9BBBBA0259}",
+ "{d7569351-1750-46f0-936e-bd127d5bc264}",
+};
+
+/** Same as above but with a "Typelib\\" prefix. */
+static const char * const g_apszTypelibGuidKeys[] =
+{
+ "TypeLib\\{46137EEC-703B-4FE5-AFD4-7C9BBBBA0259}",
+ "TypeLib\\{d7569351-1750-46f0-936e-bd127d5bc264}",
+};
+
+/** Type library version to clean up manually. */
+static const char * const g_apszTypelibVersions[] =
+{
+ "1.0",
+ "1.3",
+};
+#endif
+
+
+/*******************************************************************************
+* Internal Functions *
+*******************************************************************************/
+#ifdef WITH_MANUAL_CLEANUP
+static void removeOldMess(void);
+#endif
+
+
/////////////////////////////////////////////////////////////////////////////
// DLL Entry Point
@@ -45,7 +94,7 @@ BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
DisableThreadLibraryCalls(hInstance);
// idempotent, so doesn't harm, and needed for COM embedding scenario
- RTR3InitDll(0);
+ RTR3InitDll(RTR3INIT_FLAGS_UNOBTRUSIVE);
}
else if (dwReason == DLL_PROCESS_DETACH)
{
@@ -84,5 +133,271 @@ STDAPI DllRegisterServer(void)
STDAPI DllUnregisterServer(void)
{
- return _Module.UnregisterServer(TRUE);
+ HRESULT hrc = _Module.UnregisterServer(TRUE);
+#ifdef WITH_MANUAL_CLEANUP
+ removeOldMess();
+#endif
+ return hrc;
}
+
+#ifdef WITH_MANUAL_CLEANUP
+
+/**
+ * Checks if the typelib GUID is one of the ones we wish to clean up.
+ *
+ * @returns true if it should be cleaned up, false if not.
+ * @param pszTypelibGuid The typelib GUID as bracketed string.
+ */
+static bool isTypelibGuidToRemove(const char *pszTypelibGuid)
+{
+ unsigned i = RT_ELEMENTS(g_apszTypelibGuids);
+ while (i-- > 0)
+ if (!stricmp(g_apszTypelibGuids[i], pszTypelibGuid))
+ return true;
+ return false;
+}
+
+
+/**
+ * Checks if the typelib version is one of the ones we wish to clean up.
+ *
+ * @returns true if it should be cleaned up, false if not.
+ * @param pszTypelibVer The typelib version as string.
+ */
+static bool isTypelibVersionToRemove(const char *pszTypelibVer)
+{
+ unsigned i = RT_ELEMENTS(g_apszTypelibVersions);
+ while (i-- > 0)
+ if (!strcmp(g_apszTypelibVersions[i], pszTypelibVer))
+ return true;
+ return false;
+}
+
+
+/**
+ * Hack to clean out the class IDs belonging to obsolete typelibs on development
+ * boxes and such likes.
+ */
+static void removeOldClassIDs(HKEY hkeyClassesRoot)
+{
+ HKEY hkeyClsId;
+ LONG rc = RegOpenKeyExA(hkeyClassesRoot, "CLSID", NULL, DELETE | KEY_ENUMERATE_SUB_KEYS | KEY_QUERY_VALUE,
+ &hkeyClsId);
+ if (rc == ERROR_SUCCESS)
+ {
+ for (DWORD idxKey = 0;; idxKey++)
+ {
+ char szCurNm[128 + 128];
+ DWORD cbCurNm = 128;
+ rc = RegEnumKeyExA(hkeyClsId, idxKey, szCurNm, &cbCurNm, NULL, NULL, NULL, NULL);
+ if (rc == ERROR_NO_MORE_ITEMS)
+ break;
+
+ /*
+ * Get the typelib GUID and program ID with the class ID.
+ */
+ AssertBreak(rc == ERROR_SUCCESS);
+ strcpy(&szCurNm[cbCurNm], "\\TypeLib");
+ HKEY hkeyIfTypelib;
+ rc = RegOpenKeyExA(hkeyClsId, szCurNm, NULL, KEY_QUERY_VALUE, &hkeyIfTypelib);
+ if (rc != ERROR_SUCCESS)
+ continue;
+
+ char szTypelibGuid[128];
+ DWORD cbValue = sizeof(szTypelibGuid) - 1;
+ rc = RegQueryValueExA(hkeyIfTypelib, NULL, NULL, NULL, (PBYTE)&szTypelibGuid[0], &cbValue);
+ if (rc != ERROR_SUCCESS)
+ cbValue = 0;
+ szTypelibGuid[cbValue] = '\0';
+ RegCloseKey(hkeyIfTypelib);
+ if (!isTypelibGuidToRemove(szTypelibGuid))
+ continue;
+
+ /* ProgId */
+ strcpy(&szCurNm[cbCurNm], "\\ProgId");
+ HKEY hkeyIfProgId;
+ rc = RegOpenKeyExA(hkeyClsId, szCurNm, NULL, KEY_QUERY_VALUE, &hkeyIfProgId);
+ if (rc != ERROR_SUCCESS)
+ continue;
+
+ char szProgId[64];
+ cbValue = sizeof(szProgId) - 1;
+ rc = RegQueryValueExA(hkeyIfProgId, NULL, NULL, NULL, (PBYTE)&szProgId[0], &cbValue);
+ if (rc != ERROR_SUCCESS)
+ cbValue = 0;
+ szProgId[cbValue] = '\0';
+ RegCloseKey(hkeyIfProgId);
+ if (strnicmp(szProgId, RT_STR_TUPLE("VirtualBox.")))
+ continue;
+
+ /*
+ * Ok, it's an orphaned VirtualBox interface. Delete it.
+ */
+ szCurNm[cbCurNm] = '\0';
+ RTAssertMsg2("Should delete HCR/CLSID/%s\n", szCurNm);
+ //rc = SHDeleteKeyA(hkeyClsId, szCurNm);
+ Assert(rc == ERROR_SUCCESS);
+ }
+
+ RegCloseKey(hkeyClsId);
+ }
+}
+
+
+/**
+ * Hack to clean out the interfaces belonging to obsolete typelibs on
+ * development boxes and such likes.
+ */
+static void removeOldInterfaces(HKEY hkeyClassesRoot)
+{
+ HKEY hkeyInterface;
+ LONG rc = RegOpenKeyExA(hkeyClassesRoot, "Interface", NULL, DELETE | KEY_ENUMERATE_SUB_KEYS | KEY_QUERY_VALUE,
+ &hkeyInterface);
+ if (rc == ERROR_SUCCESS)
+ {
+ for (DWORD idxKey = 0;; idxKey++)
+ {
+ char szCurNm[128 + 128];
+ DWORD cbCurNm = 128;
+ rc = RegEnumKeyExA(hkeyInterface, idxKey, szCurNm, &cbCurNm, NULL, NULL, NULL, NULL);
+ if (rc == ERROR_NO_MORE_ITEMS)
+ break;
+
+ /*
+ * Get the typelib GUID and version associated with the interface.
+ */
+ AssertBreak(rc == ERROR_SUCCESS);
+ strcpy(&szCurNm[cbCurNm], "\\TypeLib");
+ HKEY hkeyIfTypelib;
+ rc = RegOpenKeyExA(hkeyInterface, szCurNm, NULL, KEY_QUERY_VALUE, &hkeyIfTypelib);
+ if (rc != ERROR_SUCCESS)
+ continue;
+
+ char szTypelibGuid[128];
+ DWORD cbValue = sizeof(szTypelibGuid) - 1;
+ rc = RegQueryValueExA(hkeyIfTypelib, NULL, NULL, NULL, (PBYTE)&szTypelibGuid[0], &cbValue);
+ if (rc != ERROR_SUCCESS)
+ cbValue = 0;
+ szTypelibGuid[cbValue] = '\0';
+ if (!isTypelibGuidToRemove(szTypelibGuid))
+ {
+ RegCloseKey(hkeyIfTypelib);
+ continue;
+ }
+
+ char szTypelibVer[64];
+ cbValue = sizeof(szTypelibVer) - 1;
+ rc = RegQueryValueExA(hkeyIfTypelib, "Version", NULL, NULL, (PBYTE)&szTypelibVer[0], &cbValue);
+ if (rc != ERROR_SUCCESS)
+ cbValue = 0;
+ szTypelibVer[cbValue] = '\0';
+
+ RegCloseKey(hkeyIfTypelib);
+
+ if (!isTypelibVersionToRemove(szTypelibVer))
+ continue;
+
+
+ /*
+ * Ok, it's an orphaned VirtualBox interface. Delete it.
+ */
+ szCurNm[cbCurNm] = '\0';
+ //RTAssertMsg2("Should delete HCR/Interface/%s\n", szCurNm);
+ rc = SHDeleteKeyA(hkeyInterface, szCurNm);
+ Assert(rc == ERROR_SUCCESS);
+ }
+
+ RegCloseKey(hkeyInterface);
+ }
+}
+
+
+/**
+ * Hack to clean obsolete typelibs on development boxes and such.
+ */
+static void removeOldTypelib(HKEY hkeyClassesRoot)
+{
+ /*
+ * Open it and verify the identity.
+ */
+ unsigned i = RT_ELEMENTS(g_apszTypelibGuidKeys);
+ while (i-- > 0)
+ {
+ HKEY hkeyTyplib;
+ LONG rc = RegOpenKeyExA(hkeyClassesRoot, g_apszTypelibGuidKeys[i], NULL,
+ DELETE | KEY_ENUMERATE_SUB_KEYS | KEY_QUERY_VALUE, &hkeyTyplib);
+ if (rc == ERROR_SUCCESS)
+ {
+ unsigned iVer = RT_ELEMENTS(g_apszTypelibVersions);
+ while (iVer-- > 0)
+ {
+ HKEY hkeyVer;
+ rc = RegOpenKeyExA(hkeyTyplib, g_apszTypelibVersions[iVer], NULL, KEY_READ, &hkeyVer);
+ if (rc == ERROR_SUCCESS)
+ {
+ char szValue[128];
+ DWORD cbValue = sizeof(szValue) - 1;
+ rc = RegQueryValueExA(hkeyVer, NULL, NULL, NULL, (PBYTE)&szValue[0], &cbValue);
+ if (rc == ERROR_SUCCESS)
+ {
+ szValue[cbValue] = '\0';
+ if (!strcmp(szValue, "VirtualBox Type Library"))
+ {
+ RegCloseKey(hkeyVer);
+ hkeyVer = NULL;
+
+ /*
+ * Delete the type library.
+ */
+ //RTAssertMsg2("Should delete HCR\\%s\\%s\n", g_apszTypelibGuidKeys[i], g_apszTypelibVersions[iVer]);
+ rc = SHDeleteKeyA(hkeyTyplib, g_apszTypelibVersions[iVer]);
+ Assert(rc == ERROR_SUCCESS);
+ }
+ }
+
+ if (hkeyVer != NULL)
+ RegCloseKey(hkeyVer);
+ }
+ }
+ RegCloseKey(hkeyTyplib);
+
+ /*
+ * The typelib key should be empty now, so we can try remove it (non-recursively).
+ */
+ rc = RegDeleteKeyA(hkeyClassesRoot, g_apszTypelibGuidKeys[i]);
+ Assert(rc == ERROR_SUCCESS);
+ }
+ }
+}
+
+
+/**
+ * Hack to clean out obsolete typelibs on development boxes and such.
+ */
+static void removeOldMess(void)
+{
+ /*
+ * The standard location.
+ */
+ removeOldTypelib(HKEY_CLASSES_ROOT);
+ removeOldInterfaces(HKEY_CLASSES_ROOT);
+ removeOldClassIDs(HKEY_CLASSES_ROOT);
+
+ /*
+ * Wow64 if present.
+ */
+ HKEY hkeyWow64;
+ LONG rc = RegOpenKeyExA(HKEY_CLASSES_ROOT, "Wow6432Node", NULL,
+ DELETE | KEY_ENUMERATE_SUB_KEYS | KEY_QUERY_VALUE, &hkeyWow64);
+ if (rc == ERROR_SUCCESS)
+ {
+ removeOldTypelib(hkeyWow64);
+ removeOldInterfaces(hkeyWow64);
+ removeOldClassIDs(hkeyWow64);
+
+ RegCloseKey(hkeyWow64);
+ }
+}
+
+#endif /* WITH_MANUAL_CLEANUP */
+