diff options
author | Lorry Tar Creator <lorry-tar-importer@baserock.org> | 2014-03-26 19:21:20 +0000 |
---|---|---|
committer | <> | 2014-05-08 15:03:54 +0000 |
commit | fb123f93f9f5ce42c8e5785d2f8e0edaf951740e (patch) | |
tree | c2103d76aec5f1f10892cd1d3a38e24f665ae5db /src/VBox/Main/src-client/win/dllmain.cpp | |
parent | 58ed4748338f9466599adfc8a9171280ed99e23f (diff) | |
download | VirtualBox-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.cpp | 327 |
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 */ + |