Changeset 59363 in vbox
- Timestamp:
- Jan 16, 2016 4:07:40 AM (9 years ago)
- Location:
- trunk/src/VBox
- Files:
-
- 1 added
- 4 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Installer/win/VBoxMergeApp.wxi
r59329 r59363 81 81 <File Id="file_VBoxProxyStub" Name="VBoxProxyStub.dll" KeyPath="yes" 82 82 Source="$(env.PATH_OUT)\bin\VBoxProxyStub.dll"> 83 <!-- TODO: figure how 327E3C00-EE61-462F-AED3-0DFF6CBF9904 is selected.-->84 <Class Id="{ 327E3C00-EE61-462F-AED3-0DFF6CBF9904}" Context="InprocServer32"83 <!-- Note! 0bb3b78c-1807-4249-5ba5-ea42d66af0bf is hardcoded in Main/Makefile.kmk and VBoxMergeCOM32On64.wxi --> 84 <Class Id="{0bb3b78c-1807-4249-5ba5-ea42d66af0bf}" Context="InprocServer32" 85 85 Description="PSFactoryBuffer" ThreadingModel="both" > 86 86 </Class> -
trunk/src/VBox/Installer/win/VBoxMergeCOM32On64.wxi
r59329 r59363 36 36 Source="$(env.PATH_OUT)\bin\VBoxProxyStub-x86.dll" 37 37 DiskId="$(var.Property_DiskIdCommon)"> 38 <Class Id="{327E3C00-EE61-462F-AED3-0DFF6CBF9904}" Context="InprocServer32" 38 <!-- Note! 0bb3b78c-1807-4249-5ba5-ea42d66af0bf is hardcoded in Main/Makefile.kmk and VBoxMergeApp.wix --> 39 <Class Id="{0bb3b78c-1807-4249-5ba5-ea42d66af0bf}" Context="InprocServer32" 39 40 Description="PSFactoryBuffer" ThreadingModel="both" /> 40 41 </File> -
trunk/src/VBox/Main/Makefile.kmk
r59327 r59363 858 858 VBoxClient-x86_EXTENDS = VBoxC 859 859 VBoxClient-x86_DEFS = VBOX_COM_INPROC_API_CLIENT $(VBoxC_DEFS) 860 VBoxClient-x86_INST.win = $(INST_DLL)x86/861 860 VBoxClient-x86_INCS.win = \ 862 861 $(VBoxClient-x86_0_OUTDIR) \ … … 1010 1009 DLLS += VBoxProxyStub 1011 1010 VBoxProxyStub_TEMPLATE = VBOXMAINCOMP 1012 VBoxProxyStub_DEFS = REGISTER_PROXY_DLL 1011 VBoxProxyStub_DEFS = REGISTER_PROXY_DLL \ 1012 PROXY_CLSID_IS="{0x0bb3b78c,0x1807,0x4249,{0x5b,0xa5,0xea,0x42,0xd6,0x6a,0xf0,0xbf}}" 1013 # => 0bb3b78c-1807-4249-5ba5-ea42d66af0bf: Also hardcoded in VBoxMergeCOM32On64.wxi and VBoxMergeApp.wxi! 1013 1014 VBoxProxyStub_DEFS.win.x86 = WIN32 1014 1015 VBoxProxyStub_INCS = $(VBoxCOM_0_OUTDIR)/ 1015 1016 VBoxProxyStub_SOURCES = \ 1016 $(VBoxCOM_0_OUTDIR)/dlldata.c \1017 1017 $(VBoxCOM_0_OUTDIR)/VirtualBox_p.c \ 1018 1018 $(VBoxCOM_0_OUTDIR)/VirtualBox_i.c \ 1019 1019 src-all/win/VBoxProxyStub.def \ 1020 src-all/win/VBoxProxyStub.rc 1020 src-all/win/VBoxProxyStub.rc \ 1021 src-all/win/VBoxProxyStub.c 1021 1022 src-all/win/VBoxProxyStub.rc_DEPS = $(VBoxCOM_0_OUTDIR)/VirtualBox.tlb 1022 1023 … … 1024 1025 DLLS += VBoxProxyStub-x86 1025 1026 VBoxProxyStub-x86_TEMPLATE = VBoxMainComp-x86 1026 VBoxProxyStub-x86_DEFS = REGISTER_PROXY_DLL 1027 VBoxProxyStub-x86_DEFS.win.x86 = WIN32 1027 VBoxProxyStub-x86_DEFS = $(VBoxProxyStub_DEFS) VBOX_PROXY_STUB_32_ON_64 WIN32 1028 1028 VBoxProxyStub-x86_INCS = $(VBoxCOM-x86_0_OUTDIR)/ 1029 1029 VBoxProxyStub-x86_SOURCES = \ 1030 $(VBoxCOM-x86_0_OUTDIR)/dlldata.c \1031 1030 $(VBoxCOM-x86_0_OUTDIR)/VirtualBox_p.c \ 1032 1031 $(VBoxCOM-x86_0_OUTDIR)/VirtualBox_i.c \ 1033 src-all/win/VBoxProxyStub.def \ 1034 src-all/win/VBoxProxyStub-x86.rc 1032 src-all/win/VBoxProxyStub.c \ 1033 src-all/win/VBoxProxyStub-x86.rc \ 1034 src-all/win/VBoxProxyStub.def 1035 1035 src-all/win/VBoxProxyStub-x86.rc_DEPS = $(VBoxCOM-x86_0_OUTDIR)/VirtualBox-x86.tlb 1036 1036 endif -
trunk/src/VBox/Main/src-all/win/VBoxProxyStub.c
r59360 r59363 1 1 /* $Id$ */ 2 2 /** @file 3 * VBoxC - COM DLL exports and DLL init/term. 3 * VBoxProxyStub - Proxy Stub and Typelib, COM DLL exports and DLL init/term. 4 * 5 * @remarks This is a C file and not C++ because rpcproxy.h isn't C++ clean, 6 * at least not in SDK v7.1. 4 7 */ 5 8 … … 20 23 * Header Files * 21 24 *********************************************************************************************************************************/ 22 #include "VBox/com/defs.h" 23 24 #include <SessionImpl.h> 25 #include <VirtualBoxClientImpl.h> 26 27 #include <atlbase.h> 28 #include <atlcom.h> 29 30 #include <iprt/initterm.h> 25 #define PROXY_DELEGATION /* see generated dlldata.c */ 26 #include <rpcproxy.h> 27 #include <Windows.h> 28 #include <Shlwapi.h> 29 #include <stdio.h> 30 31 #include "VirtualBox.h" 31 32 #include <iprt/assert.h> 33 #include <iprt/path.h> 32 34 #include <iprt/string.h> 35 36 37 /********************************************************************************************************************************* 38 * Defined Constants And Macros * 39 *********************************************************************************************************************************/ 40 /** @def WITH_MANUAL_CLEANUP 41 * Manually clean up the registry. */ 42 #if 1 /*defined(DEBUG) && !defined(VBOX_IN_32_ON_64_MAIN_API) - needed on testboxes (and obviously dev boxes)! */ 43 # define WITH_MANUAL_CLEANUP 44 #endif 33 45 34 46 … … 36 48 * Global Variables * 37 49 *********************************************************************************************************************************/ 38 CComModule _Module; 39 40 BEGIN_OBJECT_MAP(ObjectMap) 41 OBJECT_ENTRY(CLSID_Session, Session) 42 OBJECT_ENTRY(CLSID_VirtualBoxClient, VirtualBoxClient) 43 END_OBJECT_MAP() 44 45 46 /** @def WITH_MANUAL_CLEANUP 47 * Manually clean up the registry. */ 48 #if defined(DEBUG) && !defined(VBOX_IN_32_ON_64_MAIN_API) 49 //# define WITH_MANUAL_CLEANUP 50 #endif 50 /** For NdrXxx. */ 51 CStdPSFactoryBuffer g_ProxyStubFactory = /* see generated dlldata.c */ 52 { 53 NULL, 54 0, 55 NULL, 56 0 57 }; 58 /** Reference to VirtualBox_p.c structure. */ 59 EXTERN_PROXY_FILE(VirtualBox) /* see generated dlldata.c */ 60 /** For NdrXxx and for returning. */ 61 static const ProxyFileInfo *g_apProxyFiles[] = 62 { 63 REFERENCE_PROXY_FILE(VirtualBox), 64 NULL /* terminator */ 65 }; 66 /** The class ID for this proxy stub factory (see Makefile). */ 67 static const CLSID g_ProxyClsId = PROXY_CLSID_IS; 68 /** The instance handle of this DLL. For use in registration routines. */ 69 static HINSTANCE g_hDllSelf; 51 70 52 71 53 72 #ifdef WITH_MANUAL_CLEANUP 54 73 /** Type library GUIDs to clean up manually. */ 55 static const char * const g_apszTypelibGuids[] =74 static const char * const g_apszTypelibGuids[] = 56 75 { 57 76 "{46137EEC-703B-4FE5-AFD4-7C9BBBBA0259}", … … 60 79 61 80 /** Same as above but with a "Typelib\\" prefix. */ 62 static const char * const g_apszTypelibGuidKeys[] =81 static const char * const g_apszTypelibGuidKeys[] = 63 82 { 64 83 "TypeLib\\{46137EEC-703B-4FE5-AFD4-7C9BBBBA0259}", … … 67 86 68 87 /** Type library version to clean up manually. */ 69 static const char * const g_apszTypelibVersions[] =88 static const char * const g_apszTypelibVersions[] = 70 89 { 71 90 "1.0", … … 83 102 84 103 85 ///////////////////////////////////////////////////////////////////////////// 86 // DLL Entry Point 87 88 extern "C" 89 BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/) 90 { 91 if (dwReason == DLL_PROCESS_ATTACH) 92 { 93 _Module.Init(ObjectMap, hInstance, &LIBID_VirtualBox); 94 DisableThreadLibraryCalls(hInstance); 95 96 // idempotent, so doesn't harm, and needed for COM embedding scenario 97 RTR3InitDll(RTR3INIT_FLAGS_UNOBTRUSIVE); 98 } 99 else if (dwReason == DLL_PROCESS_DETACH) 100 { 101 _Module.Term(); 102 } 104 105 106 /** 107 * DLL main function. 108 * 109 * @returns TRUE (/ FALSE). 110 * @param hInstance The DLL handle. 111 * @param dwReason The rason for the call (DLL_XXX). 112 * @param lpReserved Reserved. 113 */ 114 BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved) 115 { 116 switch (dwReason) 117 { 118 case DLL_PROCESS_ATTACH: 119 g_hDllSelf = hInstance; 120 DisableThreadLibraryCalls(hInstance); 121 /* We don't use IPRT, so no need to init it! */ 122 break; 123 124 case DLL_PROCESS_DETACH: 125 break; 126 } 127 128 NOREF(lpReserved); 103 129 return TRUE; 104 130 } 105 131 106 ///////////////////////////////////////////////////////////////////////////// 107 // Used to determine whether the DLL can be unloaded by OLE 108 109 STDAPI DllCanUnloadNow(void) 110 { 111 return (_Module.GetLockCount()==0) ? S_OK : S_FALSE; 112 } 113 114 ///////////////////////////////////////////////////////////////////////////// 115 // Returns a class factory to create an object of the requested type 116 117 STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv) 118 { 119 return _Module.GetClassObject(rclsid, riid, ppv); 120 } 121 122 ///////////////////////////////////////////////////////////////////////////// 123 // DllRegisterServer - Adds entries to the system registry 124 125 STDAPI DllRegisterServer(void) 126 { 127 // registers object, typelib and all interfaces in typelib 128 return _Module.RegisterServer(TRUE); 129 } 130 131 ///////////////////////////////////////////////////////////////////////////// 132 // DllUnregisterServer - Removes entries from the system registry 133 134 STDAPI DllUnregisterServer(void) 135 { 136 HRESULT hrc = _Module.UnregisterServer(TRUE); 132 133 /** 134 * RPC entry point returning info about the proxy. 135 */ 136 void RPC_ENTRY GetProxyDllInfo(const ProxyFileInfo ***ppapInfo, const CLSID **ppClsid) 137 { 138 *ppapInfo = &g_apProxyFiles[0]; 139 *ppClsid = &g_ProxyClsId; 140 }; 141 142 143 /** 144 * Instantiate the proxy stub class object. 145 * 146 * @returns COM status code 147 * @param rclsid Reference to the ID of the call to instantiate (our 148 * g_ProxyClsId). 149 * @param riid The interface ID to return (IID_IPSFactoryBuffer). 150 * @param ppv Where to return the interface pointer on success. 151 */ 152 HRESULT STDAPICALLTYPE DllGetClassObject(REFCLSID rclsid, REFIID riid, void **ppv) 153 { 154 HRESULT hrc; 155 Assert(memcmp(rclsid, &g_ProxyClsId, sizeof(g_ProxyClsId)) == 0); 156 157 hrc = NdrDllGetClassObject(rclsid, riid, ppv, /* see DLLGETCLASSOBJECTROUTINE in RpcProxy.h */ 158 g_apProxyFiles, &g_ProxyClsId, &g_ProxyStubFactory); 159 160 /* 161 * This may fail if the IDL compiler generates code that is incompatible 162 * with older windows releases. Like for instance 64-bit W2K8 SP1 not 163 * liking the output of MIDL 7.00.0555 (from the v7.1 SDK), despite 164 * /target being set to NT51. 165 */ 166 AssertMsg(hrc == S_OK, ("%Rhrc\n", hrc)); 167 return hrc; 168 } 169 170 171 /** 172 * Checks whether the DLL can be unloaded or not. 173 * 174 * @returns S_OK if it can be unloaded, S_FALSE if not. 175 */ 176 HRESULT STDAPICALLTYPE DllCanUnloadNow(void) 177 { 178 return NdrDllCanUnloadNow(&g_ProxyStubFactory); /* see DLLCANUNLOADNOW in RpcProxy.h */ 179 } 180 181 182 183 /** 184 * Release call that could be referenced by VirtualBox_p.c via 185 * CStdStubBuffer_METHODS. 186 * 187 * @returns New reference count. 188 * @param pThis Buffer to release. 189 */ 190 ULONG STDMETHODCALLTYPE CStdStubBuffer_Release(IRpcStubBuffer *pThis) /* see CSTDSTUBBUFFERRELEASE in RpcProxy.h */ 191 { 192 return NdrCStdStubBuffer_Release(pThis, (IPSFactoryBuffer *)&g_ProxyStubFactory); 193 } 194 195 196 /** 197 * Release call referenced by VirtualBox_p.c via 198 * CStdStubBuffer_DELEGATING_METHODS. 199 * 200 * @returns New reference count. 201 * @param pThis Buffer to release. 202 */ 203 ULONG WINAPI CStdStubBuffer2_Release(IRpcStubBuffer *pThis) /* see CSTDSTUBBUFFER2RELEASE in RpcProxy.h */ 204 { 205 return NdrCStdStubBuffer2_Release(pThis, (IPSFactoryBuffer *)&g_ProxyStubFactory); 206 } 207 208 209 /** 210 * Pure virtual method implementation referenced by VirtualBox_p.c 211 * 212 * @returns New reference count. 213 * @param pThis Buffer to release. 214 */ 215 void __cdecl _purecall(void) /* see DLLDUMMYPURECALL in RpcProxy.h */ 216 { 217 AssertFailed(); 218 } 219 220 221 /** 222 * Registry modifier state. 223 */ 224 typedef struct VBPSREGSTATE 225 { 226 /** Where the classes and stuff are to be registered. */ 227 HKEY hkeyClassesRootDst; 228 /** The handle to the CLSID key under hkeyClassesRootDst. */ 229 HKEY hkeyClsidRootDst; 230 /** For logging purposes. */ 231 const char *pszLogRoot; 232 233 /** Alternative location where duplicates must always be unregistered from. */ 234 HKEY hkeyAltClassesRootsUnreg; 235 /** The handle to the CLSID key under hkeyAltClassesRootsUnreg. */ 236 HKEY hkeyAltClsidRootsUnreg; 237 238 /** The current total result. */ 239 LSTATUS rc; 240 241 /** KEY_WOW64_32KEY, KEY_WOW64_64KEY or 0 (for default). Allows doing all 242 * almost the work from one process (at least W7+ due to aliases). */ 243 DWORD fSamWow; 244 /** Desired key Access when only unregistring. */ 245 DWORD fSamUnreg; 246 /** Desired key Access when both unregistring and registering. */ 247 DWORD fSamBoth; 248 /** Set if we're only unregistering. */ 249 bool fUnregisterOnly; 250 } VBPSREGSTATE; 251 252 253 /** 254 * Initializes a registry modification job state. 255 * 256 * Always call vbpsRegTerm! 257 * 258 * @returns Windows error code (ERROR_SUCCESS on success). 259 * @param pState The state to init. 260 * @param hkeyRoot The registry root tree constant. 261 * @param pszSubRoot The path to the where the classes are registered, 262 * NULL if @a hkeyRoot. 263 * @param pszLogRoot For error logging/debugging? 264 * @param hkeyAltRoot The registry root tree constant for the alternative 265 * registrations (remove only). 266 * @param pszAltSubRoot The path to where classes could also be registered, 267 * but shouldn't be in our setup. 268 * @param fUnregisterOnly If true, only unregister. If false, also register. 269 * @param fSamWow KEY_WOW64_32KEY or 0. 270 */ 271 static LSTATUS vbpsRegInit(VBPSREGSTATE *pState, HKEY hkeyRoot, const char *pszSubRoot, const char *pszLogRoot, 272 HKEY hkeyAltRoot, const char *pszAltSubRoot, bool fUnregisterOnly, DWORD fSamWow) 273 { 274 LSTATUS rc; 275 REGSAM fAccess = !fUnregisterOnly 276 ? DELETE | KEY_ENUMERATE_SUB_KEYS | KEY_QUERY_VALUE | KEY_SET_VALUE | KEY_CREATE_SUB_KEY 277 : DELETE | KEY_ENUMERATE_SUB_KEYS | KEY_QUERY_VALUE; 278 279 pState->hkeyClassesRootDst = NULL; 280 pState->hkeyClsidRootDst = NULL; 281 pState->pszLogRoot = pszLogRoot; 282 pState->hkeyAltClassesRootsUnreg = NULL; 283 pState->hkeyAltClsidRootsUnreg = NULL; 284 pState->fUnregisterOnly = fUnregisterOnly; 285 pState->fSamWow = fSamWow; 286 pState->fSamUnreg = pState->fSamWow | DELETE | KEY_ENUMERATE_SUB_KEYS | KEY_QUERY_VALUE; 287 pState->fSamBoth = pState->fSamUnreg | (!fUnregisterOnly ? KEY_SET_VALUE | KEY_CREATE_SUB_KEY : 0); 288 pState->rc = ERROR_SUCCESS; 289 290 rc = RegOpenKeyExA(hkeyRoot, pszSubRoot, 0 /*fOptions*/, pState->fSamBoth, &pState->hkeyClassesRootDst); 291 AssertMsgReturn(rc == ERROR_SUCCESS, ("%u\n", rc), pState->rc = rc); 292 rc = RegOpenKeyExA(pState->hkeyClassesRootDst, "CLSID", 0 /*fOptions*/, pState->fSamBoth, &pState->hkeyClsidRootDst); 293 AssertMsgReturn(rc == ERROR_SUCCESS, ("%u\n", rc), pState->rc = rc); 294 if (hkeyAltRoot) 295 { 296 rc = RegOpenKeyExA(hkeyAltRoot, pszAltSubRoot, 0 /*fOptions*/, pState->fSamUnreg, &pState->hkeyAltClassesRootsUnreg); 297 AssertMsgReturn(rc == ERROR_SUCCESS || rc == ERROR_FILE_NOT_FOUND, ("%u\n", rc), pState->rc = rc); 298 if (pState->hkeyAltClassesRootsUnreg) 299 { 300 rc = RegOpenKeyExA(pState->hkeyAltClassesRootsUnreg, "CLSID", 0 /*fOptions*/, pState->fSamUnreg, 301 &pState->hkeyAltClsidRootsUnreg); 302 AssertMsgReturn(rc == ERROR_SUCCESS || rc == ERROR_FILE_NOT_FOUND, ("%u\n", rc), pState->rc = rc); 303 } 304 } 305 return ERROR_SUCCESS; 306 } 307 308 309 /** 310 * Terminates the state, closing all open keys. 311 * 312 * @param pState The state to clean up. 313 */ 314 static void vbpsRegTerm(VBPSREGSTATE *pState) 315 { 316 LSTATUS rc; 317 if (pState->hkeyClassesRootDst) 318 { 319 rc = RegCloseKey(pState->hkeyClassesRootDst); 320 Assert(rc == ERROR_SUCCESS); 321 pState->hkeyClassesRootDst = NULL; 322 } 323 if (pState->hkeyClsidRootDst) 324 { 325 rc = RegCloseKey(pState->hkeyClsidRootDst); 326 Assert(rc == ERROR_SUCCESS); 327 pState->hkeyClsidRootDst = NULL; 328 } 329 if (pState->hkeyAltClassesRootsUnreg) 330 { 331 rc = RegCloseKey(pState->hkeyAltClassesRootsUnreg); 332 Assert(rc == ERROR_SUCCESS); 333 pState->hkeyAltClassesRootsUnreg = NULL; 334 } 335 if (pState->hkeyAltClsidRootsUnreg) 336 { 337 rc = RegCloseKey(pState->hkeyAltClsidRootsUnreg); 338 Assert(rc == ERROR_SUCCESS); 339 pState->hkeyAltClsidRootsUnreg = NULL; 340 } 341 } 342 343 344 /** The destination buffer size required by vbpsFormatUuidInCurly. */ 345 #define CURLY_UUID_STR_BUF_SIZE 48 346 347 /** 348 * Formats a UUID to a string, inside curly braces. 349 * 350 * @returns ERROR_SUCCESS on success, otherwise windows error code. 351 * @param pszUuid Output buffer of size CURLY_UUID_STR_BUF_SIZE. 352 * @param pUuid The UUID to format. 353 */ 354 static LSTATUS vbpsFormatUuidInCurly(char *pszUuid, const CLSID *pUuid) 355 { 356 unsigned char *pszTmpStr = NULL; 357 size_t cchTmpStr; 358 RPC_STATUS rc = UuidToStringA((UUID *)pUuid, &pszTmpStr); 359 AssertReturnStmt(rc == RPC_S_OK, *pszUuid = '\0', ERROR_OUTOFMEMORY); 360 361 cchTmpStr = strlen((const char *)pszTmpStr); 362 AssertReturnStmt(cchTmpStr == 36 && cchTmpStr < CURLY_UUID_STR_BUF_SIZE - 3, RpcStringFreeA(&pszTmpStr), ERROR_INVALID_DATA); 363 364 pszUuid[0] = '{'; 365 memcpy(pszUuid + 1, pszTmpStr, cchTmpStr); 366 pszUuid[1 + cchTmpStr] = '}'; 367 pszUuid[1 + cchTmpStr + 1] = '\0'; 368 369 RpcStringFreeA(&pszTmpStr); 370 return ERROR_SUCCESS; 371 } 372 373 374 /** 375 * Sets a registry string value. 376 * 377 * @returns See RegSetValueExA (errors are remembered in the state). 378 * @param pState The registry modifier state. 379 * @param hKey The key to add the value to. 380 * @param pszValueNm The value name. NULL for setting the default. 381 * @param pszValue The value string. 382 * @param uLine The line we're called from. 383 */ 384 static LSTATUS vbpsSetRegValueAA(VBPSREGSTATE *pState, HKEY hKey, const char *pszValueNm, const char *pszValue, unsigned uLine) 385 { 386 LSTATUS rc = RegSetValueExA(hKey, pszValueNm, 0 /*Reserved*/, REG_SZ, pszValue, (DWORD)strlen(pszValue) + 1); 387 if (rc == ERROR_SUCCESS) 388 return ERROR_SUCCESS; 389 AssertMsgFailed(("%d: '%s'='%s' -> %u\n", uLine, pszValueNm, pszValue, rc)); 390 return pState->rc = rc; 391 } 392 393 /** 394 * Creates a registry key. 395 * 396 * @returns See RegCreateKeyA and RegSetValueExA (errors are remembered in the 397 * state). 398 * @param pState The registry modifier state. 399 * @param hKeyParent The parent key. 400 * @param pszKey The new key under @a hKeyParent. 401 * @param phKey Where to return the handle to the new key. 402 * @param uLine The line we're called from. 403 */ 404 static LSTATUS vbpsCreateRegKeyA(VBPSREGSTATE *pState, HKEY hKeyParent, const char *pszKey, PHKEY phKey, unsigned uLine) 405 { 406 HKEY hNewKey; 407 LSTATUS rc = RegCreateKeyExA(hKeyParent, pszKey, 0 /*Reserved*/, NULL /*pszClass*/, 0 /*fOptions*/, 408 pState->fSamBoth, NULL /*pSecAttr*/, &hNewKey, NULL /*pdwDisposition*/); 409 if (rc == ERROR_SUCCESS) 410 *phKey = hNewKey; 411 else 412 { 413 AssertMsgFailed(("%d: create key '%s' -> %u\n", uLine, pszKey, rc)); 414 pState->rc = rc; 415 *phKey = NULL; 416 } 417 return rc; 418 } 419 420 421 /** 422 * Creates a registry key with a default string value. 423 * 424 * @returns See RegCreateKeyA and RegSetValueExA (errors are remembered in the 425 * state). 426 * @param pState The registry modifier state. 427 * @param hKeyParent The parent key. 428 * @param pszKey The new key under @a hKeyParent. 429 * @param pszValue The value string. 430 * @param uLine The line we're called from. 431 */ 432 static LSTATUS vbpsCreateRegKeyWithDefaultValueAA(VBPSREGSTATE *pState, HKEY hKeyParent, const char *pszKey, 433 const char *pszValue, unsigned uLine) 434 { 435 HKEY hNewKey; 436 LSTATUS rc = vbpsCreateRegKeyA(pState, hKeyParent, pszKey, &hNewKey, uLine); 437 if (rc == ERROR_SUCCESS) 438 { 439 rc = vbpsSetRegValueAA(pState, hNewKey, NULL /*pszValueNm*/, pszValue, uLine); 440 RegCloseKey(hNewKey); 441 } 442 else 443 { 444 AssertMsgFailed(("%d: create key '%s'(/Default='%s') -> %u\n", uLine, pszKey, pszValue, rc)); 445 pState->rc = rc; 446 } 447 return rc; 448 } 449 450 451 /** 452 * Creates a registry key with a default string value, return the key. 453 * 454 * @returns See RegCreateKeyA and RegSetValueExA (errors are remembered in the 455 * state). 456 * @param pState The registry modifier state. 457 * @param hKeyParent The parent key. 458 * @param pszKey The new key under @a hKeyParent. 459 * @param pszValue The value string. 460 * @param phKey Where to return the handle to the new key. 461 * @param uLine The line we're called from. 462 */ 463 static LSTATUS vbpsCreateRegKeyWithDefaultValueAAEx(VBPSREGSTATE *pState, HKEY hKeyParent, const char *pszKey, 464 const char *pszValue, PHKEY phKey, unsigned uLine) 465 { 466 HKEY hNewKey; 467 LSTATUS rc = vbpsCreateRegKeyA(pState, hKeyParent, pszKey, &hNewKey, uLine); 468 if (rc == ERROR_SUCCESS) 469 { 470 rc = vbpsSetRegValueAA(pState, hNewKey, NULL /*pszValueNm*/, pszValue, uLine); 471 *phKey = hNewKey; 472 } 473 else 474 { 475 AssertMsgFailed(("%d: create key '%s'(/Default='%s') -> %u\n", uLine, pszKey, pszValue, rc)); 476 pState->rc = rc; 477 *phKey = NULL; 478 } 479 return rc; 480 } 481 482 483 /** 484 * Register an application id. 485 * 486 * @returns Windows error code (errors are rememberd in the state). 487 * @param pState The registry modifier state. 488 * @param pszAppId The application UUID string. 489 * @param pszDescription The description string. 490 */ 491 LSTATUS VbpsRegisterAppId(VBPSREGSTATE *pState, const char *pszAppId, const char *pszDescription) 492 { 493 LSTATUS rc; 494 HKEY hkeyAppIds; 495 Assert(*pszAppId == '{'); 496 497 /* Always unregister. */ 498 if (pState->hkeyAltClassesRootsUnreg) 499 { 500 rc = RegOpenKeyExW(pState->hkeyAltClassesRootsUnreg, L"AppID", 0 /*fOptions*/, pState->fSamUnreg, &hkeyAppIds); 501 AssertMsgStmt(rc == ERROR_SUCCESS || rc == ERROR_FILE_NOT_FOUND, ("%u\n", rc), pState->rc = rc); 502 if (rc == ERROR_SUCCESS) 503 { 504 rc = SHDeleteKeyA(hkeyAppIds, pszAppId); 505 AssertMsgStmt(rc == ERROR_SUCCESS || rc == ERROR_FILE_NOT_FOUND, ("%u\n", rc), pState->rc = rc); 506 RegCloseKey(hkeyAppIds); 507 } 508 } 509 510 rc = RegOpenKeyExW(pState->hkeyClassesRootDst, L"AppID", 0 /*fOptions*/, pState->fSamBoth, &hkeyAppIds); 511 AssertMsgReturn(rc == ERROR_SUCCESS, ("%u\n", rc), pState->rc = rc); 512 if (rc == ERROR_SUCCESS) 513 { 514 rc = SHDeleteKeyA(hkeyAppIds, pszAppId); 515 AssertMsgStmt(rc == ERROR_SUCCESS || rc == ERROR_FILE_NOT_FOUND, ("%u\n", rc), pState->rc = rc); 516 } 517 518 /* Register */ 519 if (!pState->fUnregisterOnly) 520 vbpsCreateRegKeyWithDefaultValueAA(pState, hkeyAppIds, pszAppId, pszDescription, __LINE__); 521 522 RegCloseKey(hkeyAppIds); 523 524 return pState->rc; 525 } 526 527 528 /** 529 * Register an class name. 530 * 531 * @returns Windows error code (errors are rememberd in the state). 532 * @param pState The registry modifier state. 533 * @param pszClassName The name of the class. 534 * @param pszDescription The description string 535 * @param pClsId The UUID for the class. 536 * @param pszCurVerSuffIfRootName This is the current version suffix to 537 * append to @a pszClassName when 538 * registering the version idependent name. 539 */ 540 LSTATUS VbpsRegisterClassName(VBPSREGSTATE *pState, const char *pszClassName, const char *pszDescription, 541 const CLSID *pClsId, const char *pszCurVerSuffIfRootName) 542 { 543 LSTATUS rc; 544 545 /* 546 * Always unregister. 547 */ 548 if (pState->hkeyAltClassesRootsUnreg) 549 { 550 rc = SHDeleteKeyA(pState->hkeyAltClassesRootsUnreg, pszClassName); 551 AssertMsgStmt(rc == ERROR_SUCCESS || rc == ERROR_FILE_NOT_FOUND, ("%u\n", rc), pState->rc = rc); 552 } 553 554 rc = SHDeleteKeyA(pState->hkeyClassesRootDst, pszClassName); 555 AssertMsgStmt(rc == ERROR_SUCCESS || rc == ERROR_FILE_NOT_FOUND, ("%u\n", rc), pState->rc = rc); 556 557 if (!pState->fUnregisterOnly) 558 { 559 /* 560 * Register 561 */ 562 /* pszClassName/Default = description. */ 563 HKEY hkeyClass; 564 rc = vbpsCreateRegKeyWithDefaultValueAAEx(pState, pState->hkeyClassesRootDst, pszClassName, pszDescription, 565 &hkeyClass, __LINE__); 566 if (rc == ERROR_SUCCESS) 567 { 568 char szClsId[CURLY_UUID_STR_BUF_SIZE]; 569 570 /* CLSID/Default = pClsId. */ 571 rc = vbpsFormatUuidInCurly(szClsId, pClsId); 572 AssertMsgStmt(rc == ERROR_SUCCESS, ("%u\n", rc), pState->rc = rc); 573 if (rc == ERROR_SUCCESS) 574 vbpsCreateRegKeyWithDefaultValueAA(pState, hkeyClass, "CLSID", szClsId, __LINE__); 575 576 /* CurVer/Default = pszClassName+Suffix. */ 577 if (pszCurVerSuffIfRootName != NULL) 578 { 579 char szCurClassNameVer[128]; 580 rc = RTStrCopy(szCurClassNameVer, sizeof(szCurClassNameVer), pszClassName); 581 if (RT_SUCCESS(rc)) 582 rc = RTStrCat(szCurClassNameVer, sizeof(szCurClassNameVer), pszCurVerSuffIfRootName); 583 AssertStmt(RT_SUCCESS(rc), pState->rc = rc = ERROR_INVALID_DATA); 584 if (rc == ERROR_SUCCESS) 585 vbpsCreateRegKeyWithDefaultValueAA(pState, hkeyClass, "CurVer", szCurClassNameVer, __LINE__); 586 } 587 588 RegCloseKey(hkeyClass); 589 } 590 } 591 592 return pState->rc; 593 } 594 595 596 /** 597 * Registers a class ID. 598 * 599 * @returns Windows error code (errors are rememberd in the state). 600 * @param pState The registry modifier state. 601 * @param pClsId The UUID for the class. 602 * @param pszDescription The description string. 603 * @param pszAppId The application ID. 604 * @param pszClassName The version idependent class name. 605 * @param pszCurClassNameVerSuffix The suffix to add to @a pszClassName for 606 * the current version. 607 * @param pTypeLibId The UUID for the typelib this class 608 * belongs to. 609 * @param pszServerType The server type (InprocServer32 or 610 * LocalServer32). 611 * @param pwszVBoxDir The VirtualBox install directory 612 * (unicode), trailing slash. 613 * @param pszServerSubPath What to append to @a pwszVBoxDir to 614 * construct the server module name. 615 * @param pszThreadingModel The threading model for inproc servers, 616 * NULL for local servers. 617 */ 618 LSTATUS VbpsRegisterClassId(VBPSREGSTATE *pState, const CLSID *pClsId, const char *pszDescription, const char *pszAppId, 619 const char *pszClassName, const char *pszCurClassNameVerSuffix, const CLSID *pTypeLibId, 620 const char *pszServerType, PCRTUTF16 pwszVBoxDir, const char *pszServerSubPath, 621 const char *pszThreadingModel) 622 { 623 LSTATUS rc; 624 char szClsId[CURLY_UUID_STR_BUF_SIZE]; 625 char szTypeLibId[CURLY_UUID_STR_BUF_SIZE]; 626 627 Assert(!pszAppId || *pszAppId == '{'); 628 Assert((pwszVBoxDir == NULL && pState->fUnregisterOnly) || pwszVBoxDir[RTUtf16Len(pwszVBoxDir) - 1] == '\\'); 629 630 /* 631 * Format the UUID first to get it over with. We always need CLSID. 632 */ 633 rc = vbpsFormatUuidInCurly(szClsId, pClsId); 634 AssertMsgReturn(rc == ERROR_SUCCESS, ("%u\n", rc), pState->rc = rc); 635 if (pTypeLibId) 636 { 637 rc = vbpsFormatUuidInCurly(szTypeLibId, pTypeLibId); 638 AssertMsgReturn(rc == ERROR_SUCCESS, ("%u\n", rc), pState->rc = rc); 639 } 640 else 641 szTypeLibId[0] = '\0'; 642 643 /* 644 * Always unregister. 645 */ 646 if (pState->hkeyAltClsidRootsUnreg) 647 { 648 rc = SHDeleteKeyA(pState->hkeyAltClsidRootsUnreg, szClsId); 649 AssertMsgStmt(rc == ERROR_SUCCESS || rc == ERROR_FILE_NOT_FOUND, ("%u\n", rc), pState->rc = rc); 650 } 651 652 rc = SHDeleteKeyA(pState->hkeyClsidRootDst, szClsId); 653 AssertMsgStmt(rc == ERROR_SUCCESS || rc == ERROR_FILE_NOT_FOUND, ("%u\n", rc), pState->rc = rc); 654 655 if (!pState->fUnregisterOnly) 656 { 657 /* 658 * Register 659 */ 660 HKEY hkeyClass; 661 rc = vbpsCreateRegKeyWithDefaultValueAAEx(pState, pState->hkeyClsidRootDst, szClsId, pszDescription, 662 &hkeyClass, __LINE__); 663 if (rc == ERROR_SUCCESS) 664 { 665 HKEY hkeyServerType; 666 char szCurClassNameVer[128]; 667 668 /* pszServerType/Default = module. */ 669 rc = vbpsCreateRegKeyA(pState, hkeyClass, pszServerType, &hkeyServerType, __LINE__); 670 if (rc == ERROR_SUCCESS) 671 { 672 RTUTF16 wszModule[MAX_PATH * 2]; 673 PRTUTF16 pwszCur = wszModule; 674 bool fQuoteIt = strcmp(pszServerType, "LocalServer32") == 0; 675 if (fQuoteIt) 676 *pwszCur++ = '"'; 677 678 rc = RTUtf16Copy(pwszCur, MAX_PATH, pwszVBoxDir); AssertRC(rc); 679 pwszCur += RTUtf16Len(pwszCur); 680 rc = RTUtf16CopyAscii(pwszCur, MAX_PATH - 3, pszServerSubPath); AssertRC(rc); 681 pwszCur += RTUtf16Len(pwszCur); 682 683 if (fQuoteIt) 684 *pwszCur++ = '"'; 685 *pwszCur++ = '\0'; /* included, so ++. */ 686 687 rc = RegSetValueExW(hkeyServerType, NULL /*pszValueNm*/, 0 /*Reserved*/, 688 REG_SZ, (const BYTE *)&wszModule[0], (DWORD)((uintptr_t)pwszCur - (uintptr_t)&wszModule[0])); 689 AssertMsgStmt(rc == ERROR_SUCCESS, ("%u\n", rc), pState->rc = rc); 690 691 /* pszServerType/ThreadingModel = pszThreading Model. */ 692 if (pszThreadingModel) 693 vbpsSetRegValueAA(pState, hkeyServerType, "ThreadingModel", pszThreadingModel, __LINE__); 694 695 RegCloseKey(hkeyServerType); 696 } 697 698 /* ProgId/Default = pszClassName + pszCurClassNameVerSuffix. */ 699 if (pszClassName) 700 { 701 rc = RTStrCopy(szCurClassNameVer, sizeof(szCurClassNameVer), pszClassName); 702 if (RT_SUCCESS(rc)) 703 rc = RTStrCat(szCurClassNameVer, sizeof(szCurClassNameVer), pszCurClassNameVerSuffix); 704 AssertStmt(RT_SUCCESS(rc), pState->rc = rc = ERROR_INVALID_DATA); 705 if (rc == ERROR_SUCCESS) 706 vbpsCreateRegKeyWithDefaultValueAA(pState, hkeyClass, "ProgId", szCurClassNameVer, __LINE__); 707 708 /* VersionIndependentProgID/Default = pszClassName. */ 709 vbpsCreateRegKeyWithDefaultValueAA(pState, hkeyClass, "VersionIndependentProgID", pszClassName, __LINE__); 710 } 711 712 /* TypeLib/Default = pTypeLibId. */ 713 if (pTypeLibId) 714 vbpsCreateRegKeyWithDefaultValueAA(pState, hkeyClass, "TypeLib", szTypeLibId, __LINE__); 715 716 RegCloseKey(hkeyClass); 717 } 718 } 719 720 return pState->rc; 721 } 722 723 724 /** 725 * Register modules and classes from the VirtualBox.xidl file. 726 * 727 * @returns COM status code. 728 * @param pwszVBoxDir The VirtualBox application directory. 729 * @param fIs32On64 Set if this is the 32-bit on 64-bit component. 730 * 731 * @todo convert to XSLT. 732 */ 733 void RegisterXidlModulesAndClassesGenerated(VBPSREGSTATE *pState, PCRTUTF16 pwszVBoxDir, bool fIs32On64) 734 { 735 const char *pszAppId = "{819B4D85-9CEE-493C-B6FC-64FFE759B3C9}"; 736 const char *pszInprocDll = !fIs32On64 ? "VBoxC.dll" : "x86\\VBoxClient-x86.dll"; 737 738 VbpsRegisterAppId(pState, pszAppId, "VirtualBox Application"); 739 740 /* VBoxSVC */ 741 VbpsRegisterClassName(pState, "VirtualBox.VirtualBox.1", "VirtualBox Class", &CLSID_VirtualBox, NULL); 742 VbpsRegisterClassName(pState, "VirtualBox.VirtualBox", "VirtualBox Class", &CLSID_VirtualBox, ".1"); 743 VbpsRegisterClassId(pState, &CLSID_VirtualBox, "VirtualBox Class", pszAppId, "VirtualBox.VirtualBox", ".1", 744 &LIBID_VirtualBox, "LocalServer32", pwszVBoxDir, "VBoxSVC.exe", NULL /*N/A*/); 745 /* VBoxC */ 746 VbpsRegisterClassName(pState, "VirtualBox.Session.1", "Session Class", &CLSID_Session, NULL); 747 VbpsRegisterClassName(pState, "VirtualBox.Session", "Session Class", &CLSID_Session, "VirtualBox.Session.1"); 748 VbpsRegisterClassId(pState, &CLSID_Session, "Session Class", pszAppId, "VirtualBox.Session", ".1", 749 &LIBID_VirtualBox, "InprocServer32", pwszVBoxDir, pszInprocDll, "Free"); 750 751 VbpsRegisterClassName(pState, "VirtualBox.VirtualBoxClient.1", "VirtualBoxClient Class", &CLSID_VirtualBoxClient, NULL); 752 VbpsRegisterClassName(pState, "VirtualBox.VirtualBoxClient", "VirtualBoxClient Class", &CLSID_VirtualBoxClient, ".1"); 753 VbpsRegisterClassId(pState, &CLSID_VirtualBoxClient, "VirtualBoxClient Class", pszAppId, 754 "VirtualBox.VirtualBoxClient", ".1", 755 &LIBID_VirtualBox, "InprocServer32", pwszVBoxDir, pszInprocDll, "Free"); 756 757 } 758 759 #ifndef VBOX_PROXY_STUB_32_ON_64 760 void RegisterOtherProxyStubAndTypelibDll(VBPSREGSTATE *pState, PCRTUTF16 pwszVBoxDir, bool fIs32On64) 761 { 762 if (!pState->fUnregisterOnly) 763 { 764 const char *pszWinXx = !fIs32On64 ? "win64" : "win32"; 765 const char *pszPsDll = !fIs32On64 ? "VBoxProxyStub.dll" : "VBoxProxyStub-x86.dll"; 766 char szTypeLibId[CURLY_UUID_STR_BUF_SIZE]; 767 char szMajMin[64]; 768 HKEY hKeyTypeLibs; 769 HKEY hKeyTypeLibId; 770 HKEY hKeyMajMin; 771 HKEY hKey0; 772 HKEY hKeyWinXx; 773 LSTATUS rc; 774 775 /* Proxy stub factory class ID. */ 776 VbpsRegisterClassId(pState, &g_ProxyClsId, "PSFactoryBuffer", NULL /*pszAppId*/, 777 NULL /*pszClassName*/, NULL /*pszCurClassNameVerSuffix*/, NULL /*pTypeLibId*/, 778 "InprocServer32", pwszVBoxDir, pszPsDll, "Both"); 779 780 /* 781 * Typelib DLL. 782 */ 783 rc = vbpsFormatUuidInCurly(szTypeLibId, &LIBID_VirtualBox); 784 AssertMsgReturnVoidStmt(rc == ERROR_SUCCESS, ("%u\n", rc), pState->rc = rc); 785 786 rc = RegOpenKeyExA(pState->hkeyClassesRootDst, "TypeLib", 0 /*fOptions*/, pState->fSamBoth, &hKeyTypeLibs); 787 AssertMsgReturnVoidStmt(rc == ERROR_SUCCESS, ("%u\n", rc), pState->rc = rc); 788 rc = RegOpenKeyExA(hKeyTypeLibs, szTypeLibId, 0 /*fOptions*/, pState->fSamBoth, &hKeyTypeLibId); 789 if (rc == ERROR_FILE_NOT_FOUND) 790 rc = vbpsCreateRegKeyA(pState, hKeyTypeLibs, szTypeLibId, &hKeyTypeLibId, __LINE__); 791 RegCloseKey(hKeyTypeLibs); 792 793 AssertMsgReturnVoidStmt(rc == ERROR_SUCCESS, ("%u\n", rc), pState->rc = rc); 794 795 /* Major.Minor/Default = Name. */ 796 sprintf(szMajMin, "%u.%u", kTypeLibraryMajorVersion, kTypeLibraryMinorVersion); 797 rc = RegOpenKeyExA(hKeyTypeLibId, szMajMin, 0 /*fOptions*/, pState->fSamBoth, &hKeyMajMin); 798 if (rc == ERROR_FILE_NOT_FOUND) 799 rc = vbpsCreateRegKeyWithDefaultValueAAEx(pState, hKeyTypeLibId, szMajMin, "VirtualBox Type Library", 800 &hKeyMajMin, __LINE__); 801 RegCloseKey(hKeyTypeLibId); 802 AssertMsgReturnVoidStmt(rc == ERROR_SUCCESS, ("%u\n", rc), pState->rc = rc); 803 804 /* 0/. */ 805 rc = RegOpenKeyExA(hKeyMajMin, "0", 0 /*fOptions*/, pState->fSamBoth, &hKey0); 806 if (rc == ERROR_FILE_NOT_FOUND) 807 rc = vbpsCreateRegKeyA(pState, hKeyMajMin, "0", &hKey0, __LINE__); 808 RegCloseKey(hKeyMajMin); 809 AssertMsgReturnVoidStmt(rc == ERROR_SUCCESS, ("%u\n", rc), pState->rc = rc); 810 811 /* winXx/Default = VBoxProxyStub. */ 812 rc = RegOpenKeyExA(hKey0, pszWinXx, 0 /*fOptions*/, pState->fSamBoth, &hKeyWinXx); 813 if (rc == ERROR_FILE_NOT_FOUND) 814 { 815 RTUTF16 wszDllPath[MAX_PATH * 2]; 816 817 rc = RTUtf16Copy(wszDllPath, MAX_PATH, pwszVBoxDir); AssertRC(rc); 818 rc = RTUtf16CatAscii(wszDllPath, MAX_PATH * 2, pszPsDll); AssertRC(rc); 819 820 rc = vbpsCreateRegKeyA(pState, hKey0, pszWinXx, &hKeyWinXx, __LINE__); 821 if (rc == ERROR_SUCCESS) 822 { 823 rc = RegSetValueExW(hKeyWinXx, NULL /*pszValueNm*/, 0 /*Reserved*/, 824 REG_SZ, (const BYTE *)&wszDllPath[0], (DWORD)((RTUtf16Len(wszDllPath) + 1 )* 2)); 825 AssertMsgStmt(rc == ERROR_SUCCESS, ("%u\n", rc), pState->rc = rc); 826 } 827 } 828 RegCloseKey(hKey0); 829 AssertMsgReturnVoidStmt(rc == ERROR_SUCCESS, ("%u\n", rc), pState->rc = rc); 830 RegCloseKey(hKeyWinXx); 831 } 832 833 } 834 #endif 835 836 837 HRESULT RegisterXidlModulesAndClasses(PRTUTF16 pwszDllName, bool fUnregisterOnly) 838 { 839 VBPSREGSTATE State; 840 LSTATUS rc; 841 842 /* 843 * Drop the filename and get the directory containing the DLL. 844 */ 845 if (!fUnregisterOnly) 846 { 847 RTUTF16 wc; 848 size_t off = RTUtf16Len(pwszDllName); 849 while ( off > 0 850 && ( (wc = pwszDllName[off - 1]) >= 127U 851 || !RTPATH_IS_SEP((unsigned char)wc))) 852 off--; 853 #ifdef VBOX_PROXY_STUB_32_ON_64 854 /* The -x86 variant is in a x86 subdirectory, drop it. */ 855 while ( off > 0 856 && ( (wc = pwszDllName[off - 1]) < 127U 857 && RTPATH_IS_SEP((unsigned char)wc))) 858 off--; 859 while ( off > 0 860 && ( (wc = pwszDllName[off - 1]) >= 127U 861 || !RTPATH_IS_SEP((unsigned char)wc))) 862 off--; 863 #endif 864 pwszDllName[off] = '\0'; 865 } 866 867 /* 868 * Do registration for the current execution mode of the DLL. 869 */ 870 rc = vbpsRegInit(&State, 871 HKEY_CLASSES_ROOT, NULL, "HKCR", /* HKEY_LOCAL_MACHINE, "Software\\Classes", "HKLM\\Software\\Classes", */ 872 HKEY_CURRENT_USER, "Software\\Classes", 873 fUnregisterOnly, 0); 874 if (rc == ERROR_SUCCESS) 875 { 876 #ifdef VBOX_PROXY_STUB_32_ON_64 877 RegisterXidlModulesAndClassesGenerated(&State, pwszDllName, true); 878 #else 879 RegisterXidlModulesAndClassesGenerated(&State, pwszDllName, false); 880 #endif 881 rc = State.rc; 882 } 883 884 vbpsRegTerm(&State); 885 886 #ifndef VBOX_PROXY_STUB_32_ON_64 887 /* 888 * Do the WOW6432Node registrations too. 889 */ 890 if (rc == ERROR_SUCCESS) 891 { 892 rc = vbpsRegInit(&State, 893 HKEY_CLASSES_ROOT, "Wow6432Node", "HKCR\\Wow6432Node", 894 HKEY_CURRENT_USER, "Software\\Classes", 895 fUnregisterOnly, KEY_WOW64_32KEY); 896 if (rc == ERROR_SUCCESS) 897 { 898 RegisterXidlModulesAndClassesGenerated(&State, pwszDllName, true); 899 RegisterOtherProxyStubAndTypelibDll(&State, pwszDllName, true); 900 rc = State.rc; 901 } 902 vbpsRegTerm(&State); 903 } 904 #endif 905 906 /* 907 * Translate error code? Return. 908 */ 909 if (rc == ERROR_SUCCESS) 910 return S_OK; 911 return E_FAIL; 912 } 913 914 915 /** 916 * Register the interfaces proxied by this DLL, and to avoid duplication and 917 * minimize work the VBox type library, classes and servers are also registered. 918 * 919 * @returns COM status code. 920 */ 921 HRESULT STDAPICALLTYPE DllRegisterServer(void) 922 { 923 HRESULT hrc; 924 925 /* 926 * Register the type library first. 927 */ 928 ITypeLib *pITypeLib; 929 WCHAR wszDllName[MAX_PATH]; 930 DWORD cwcRet = GetModuleFileNameW(g_hDllSelf, wszDllName, RT_ELEMENTS(wszDllName)); 931 AssertReturn(cwcRet > 0 && cwcRet < RT_ELEMENTS(wszDllName), CO_E_PATHTOOLONG); 932 933 hrc = LoadTypeLib(wszDllName, &pITypeLib); 934 AssertMsgReturn(SUCCEEDED(hrc), ("%Rhrc\n", hrc), hrc); 935 hrc = RegisterTypeLib(pITypeLib, wszDllName, NULL /*pszHelpDir*/); 936 pITypeLib->lpVtbl->Release(pITypeLib); 937 AssertMsgReturn(SUCCEEDED(hrc), ("%Rhrc\n", hrc), hrc); 938 939 /* 940 * Register proxy stub. 941 */ 942 hrc = NdrDllRegisterProxy(g_hDllSelf, &g_apProxyFiles[0], &g_ProxyClsId); /* see DLLREGISTRY_ROUTINES in RpcProxy.h */ 943 AssertMsgReturn(SUCCEEDED(hrc), ("%Rhrc\n", hrc), hrc); 944 945 /* 946 * Register the VBox modules and classes. 947 */ 948 hrc = RegisterXidlModulesAndClasses(wszDllName, false /*fUnregisterOnly*/); 949 AssertMsgReturn(SUCCEEDED(hrc), ("%Rhrc\n", hrc), hrc); 950 951 return S_OK; 952 } 953 954 955 /** 956 * Reverse of DllRegisterServer. 957 * 958 * @returns COM status code. 959 */ 960 HRESULT STDAPICALLTYPE DllUnregisterServer(void) 961 { 962 HRESULT hrc = S_OK; 963 HRESULT hrc2; 964 965 /* 966 * Unregister the type library. 967 * 968 * We ignore TYPE_E_REGISTRYACCESS as that is what is returned if the 969 * type lib hasn't been registered (W10). 970 */ 971 hrc2 = UnRegisterTypeLib(&LIBID_VirtualBox, kTypeLibraryMajorVersion, kTypeLibraryMinorVersion, 972 0 /*LCid*/, RT_CONCAT(SYS_WIN, ARCH_BITS)); 973 AssertMsgStmt(SUCCEEDED(hrc2) || hrc2 == TYPE_E_REGISTRYACCESS, ("%Rhrc\n", hrc2), if (SUCCEEDED(hrc)) hrc = hrc2); 974 975 /* 976 * Unregister the proxy stub. 977 * 978 * We ignore ERROR_FILE_NOT_FOUND as that is returned if not registered (W10). 979 */ 980 hrc2 = NdrDllUnregisterProxy(g_hDllSelf, &g_apProxyFiles[0], &g_ProxyClsId); /* see DLLREGISTRY_ROUTINES in RpcProxy.h */ 981 AssertMsgStmt( SUCCEEDED(hrc2) 982 || hrc2 == MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_FILE_NOT_FOUND), 983 ("%Rhrc\n", hrc2), if (SUCCEEDED(hrc)) hrc = hrc2); 984 985 /* 986 * Register the VBox modules and classes. 987 */ 988 hrc2 = RegisterXidlModulesAndClasses(NULL, true /*fUnregisterOnly*/); 989 AssertMsgStmt(SUCCEEDED(hrc2), ("%Rhrc\n", hrc2), if (SUCCEEDED(hrc)) hrc = hrc2); 990 137 991 #ifdef WITH_MANUAL_CLEANUP 992 /* 993 * Purge old mess. 994 */ 138 995 removeOldMess(); 139 996 #endif 997 140 998 return hrc; 141 999 } … … 182 1040 { 183 1041 HKEY hkeyClsId; 184 LONG rc = RegOpenKeyExA(hkeyClassesRoot, "CLSID", NULL, DELETE | KEY_ENUMERATE_SUB_KEYS | KEY_QUERY_VALUE,1042 LONG rc = RegOpenKeyExA(hkeyClassesRoot, "CLSID", 0, DELETE | KEY_ENUMERATE_SUB_KEYS | KEY_QUERY_VALUE, 185 1043 &hkeyClsId); 186 1044 if (rc == ERROR_SUCCESS) 187 1045 { 188 for (DWORD idxKey = 0;; idxKey++) 1046 DWORD idxKey; 1047 for (idxKey = 0;; idxKey++) 189 1048 { 190 1049 char szCurNm[128 + 128]; 191 1050 DWORD cbCurNm = 128; 192 1051 rc = RegEnumKeyExA(hkeyClsId, idxKey, szCurNm, &cbCurNm, NULL, NULL, NULL, NULL); 193 if (rc == ERROR_NO_MORE_ITEMS) 1052 if (rc == ERROR_SUCCESS) 1053 { 1054 /* 1055 * Get the typelib GUID and program ID with the class ID. 1056 */ 1057 HKEY hkeyIfTypelib; 1058 strcpy(&szCurNm[cbCurNm], "\\TypeLib"); 1059 rc = RegOpenKeyExA(hkeyClsId, szCurNm, 0, KEY_QUERY_VALUE, &hkeyIfTypelib); 1060 if (rc == ERROR_SUCCESS) 1061 { 1062 char szTypelibGuid[128]; 1063 DWORD cbValue = sizeof(szTypelibGuid) - 1; 1064 rc = RegQueryValueExA(hkeyIfTypelib, NULL, NULL, NULL, (PBYTE)&szTypelibGuid[0], &cbValue); 1065 if (rc != ERROR_SUCCESS) 1066 cbValue = 0; 1067 szTypelibGuid[cbValue] = '\0'; 1068 RegCloseKey(hkeyIfTypelib); 1069 if (isTypelibGuidToRemove(szTypelibGuid)) 1070 { 1071 /* ProgId */ 1072 HKEY hkeyIfProgId; 1073 strcpy(&szCurNm[cbCurNm], "\\ProgId"); 1074 rc = RegOpenKeyExA(hkeyClsId, szCurNm, 0, KEY_QUERY_VALUE, &hkeyIfProgId); 1075 if (rc == ERROR_SUCCESS) 1076 { 1077 char szProgId[64]; 1078 cbValue = sizeof(szProgId) - 1; 1079 rc = RegQueryValueExA(hkeyIfProgId, NULL, NULL, NULL, (PBYTE)&szProgId[0], &cbValue); 1080 if (rc != ERROR_SUCCESS) 1081 cbValue = 0; 1082 szProgId[cbValue] = '\0'; 1083 RegCloseKey(hkeyIfProgId); 1084 if ( rc == ERROR_SUCCESS 1085 && strnicmp(szProgId, RT_STR_TUPLE("VirtualBox.")) == 0) 1086 { 1087 /* 1088 * Ok, it's an orphaned VirtualBox interface. Delete it. 1089 */ 1090 szCurNm[cbCurNm] = '\0'; 1091 #ifdef DEBUG_bird 1092 RTAssertMsg2("Should delete HCR/CLSID/%s\n", szCurNm); 1093 #endif 1094 rc = SHDeleteKeyA(hkeyClsId, szCurNm); 1095 Assert(rc == ERROR_SUCCESS); 1096 } 1097 } 1098 } 1099 } 1100 1101 } 1102 else 1103 { 1104 Assert(rc == ERROR_NO_MORE_ITEMS); 194 1105 break; 195 196 /* 197 * Get the typelib GUID and program ID with the class ID. 198 */ 199 AssertBreak(rc == ERROR_SUCCESS); 200 strcpy(&szCurNm[cbCurNm], "\\TypeLib"); 201 HKEY hkeyIfTypelib; 202 rc = RegOpenKeyExA(hkeyClsId, szCurNm, NULL, KEY_QUERY_VALUE, &hkeyIfTypelib); 203 if (rc != ERROR_SUCCESS) 204 continue; 205 206 char szTypelibGuid[128]; 207 DWORD cbValue = sizeof(szTypelibGuid) - 1; 208 rc = RegQueryValueExA(hkeyIfTypelib, NULL, NULL, NULL, (PBYTE)&szTypelibGuid[0], &cbValue); 209 if (rc != ERROR_SUCCESS) 210 cbValue = 0; 211 szTypelibGuid[cbValue] = '\0'; 212 RegCloseKey(hkeyIfTypelib); 213 if (!isTypelibGuidToRemove(szTypelibGuid)) 214 continue; 215 216 /* ProgId */ 217 strcpy(&szCurNm[cbCurNm], "\\ProgId"); 218 HKEY hkeyIfProgId; 219 rc = RegOpenKeyExA(hkeyClsId, szCurNm, NULL, KEY_QUERY_VALUE, &hkeyIfProgId); 220 if (rc != ERROR_SUCCESS) 221 continue; 222 223 char szProgId[64]; 224 cbValue = sizeof(szProgId) - 1; 225 rc = RegQueryValueExA(hkeyIfProgId, NULL, NULL, NULL, (PBYTE)&szProgId[0], &cbValue); 226 if (rc != ERROR_SUCCESS) 227 cbValue = 0; 228 szProgId[cbValue] = '\0'; 229 RegCloseKey(hkeyIfProgId); 230 if (strnicmp(szProgId, RT_STR_TUPLE("VirtualBox."))) 231 continue; 232 233 /* 234 * Ok, it's an orphaned VirtualBox interface. Delete it. 235 */ 236 szCurNm[cbCurNm] = '\0'; 237 RTAssertMsg2("Should delete HCR/CLSID/%s\n", szCurNm); 238 //rc = SHDeleteKeyA(hkeyClsId, szCurNm); 239 Assert(rc == ERROR_SUCCESS); 1106 } 240 1107 } 241 1108 … … 252 1119 { 253 1120 HKEY hkeyInterface; 254 LONG rc = RegOpenKeyExA(hkeyClassesRoot, "Interface", NULL, DELETE | KEY_ENUMERATE_SUB_KEYS | KEY_QUERY_VALUE,1121 LONG rc = RegOpenKeyExA(hkeyClassesRoot, "Interface", 0, DELETE | KEY_ENUMERATE_SUB_KEYS | KEY_QUERY_VALUE, 255 1122 &hkeyInterface); 256 1123 if (rc == ERROR_SUCCESS) 257 1124 { 258 for (DWORD idxKey = 0;; idxKey++) 1125 DWORD idxKey; 1126 for (idxKey = 0;; idxKey++) 259 1127 { 260 1128 char szCurNm[128 + 128]; 261 1129 DWORD cbCurNm = 128; 262 1130 rc = RegEnumKeyExA(hkeyInterface, idxKey, szCurNm, &cbCurNm, NULL, NULL, NULL, NULL); 263 if (rc == ERROR_NO_MORE_ITEMS) 1131 if (rc == ERROR_SUCCESS) 1132 { 1133 /* 1134 * Get the typelib GUID and version associated with the interface. 1135 */ 1136 HKEY hkeyIfTypelib; 1137 strcpy(&szCurNm[cbCurNm], "\\TypeLib"); 1138 rc = RegOpenKeyExA(hkeyInterface, szCurNm, 0, KEY_QUERY_VALUE, &hkeyIfTypelib); 1139 if (rc == ERROR_SUCCESS) 1140 { 1141 char szTypelibGuid[128]; 1142 DWORD cbValue = sizeof(szTypelibGuid) - 1; 1143 rc = RegQueryValueExA(hkeyIfTypelib, 0, NULL, NULL, (PBYTE)&szTypelibGuid[0], &cbValue); 1144 if (rc != ERROR_SUCCESS) 1145 cbValue = 0; 1146 szTypelibGuid[cbValue] = '\0'; 1147 if ( rc == ERROR_SUCCESS 1148 && isTypelibGuidToRemove(szTypelibGuid)) 1149 { 1150 char szTypelibVer[64]; 1151 cbValue = sizeof(szTypelibVer) - 1; 1152 rc = RegQueryValueExA(hkeyIfTypelib, "Version", 0, NULL, (PBYTE)&szTypelibVer[0], &cbValue); 1153 if (rc != ERROR_SUCCESS) 1154 cbValue = 0; 1155 szTypelibVer[cbValue] = '\0'; 1156 1157 if ( rc == ERROR_SUCCESS 1158 && isTypelibVersionToRemove(szTypelibVer)) 1159 { 1160 /* 1161 * Ok, it's an orphaned VirtualBox interface. Delete it. 1162 */ 1163 szCurNm[cbCurNm] = '\0'; 1164 RTAssertMsg2("Should delete HCR/Interface/%s\n", szCurNm); 1165 rc = SHDeleteKeyA(hkeyInterface, szCurNm); 1166 Assert(rc == ERROR_SUCCESS); 1167 } 1168 } 1169 RegCloseKey(hkeyIfTypelib); 1170 } 1171 } 1172 else 1173 { 1174 Assert(rc == ERROR_NO_MORE_ITEMS); 264 1175 break; 265 266 /*267 * Get the typelib GUID and version associated with the interface.268 */269 AssertBreak(rc == ERROR_SUCCESS);270 strcpy(&szCurNm[cbCurNm], "\\TypeLib");271 HKEY hkeyIfTypelib;272 rc = RegOpenKeyExA(hkeyInterface, szCurNm, NULL, KEY_QUERY_VALUE, &hkeyIfTypelib);273 if (rc != ERROR_SUCCESS)274 continue;275 276 char szTypelibGuid[128];277 DWORD cbValue = sizeof(szTypelibGuid) - 1;278 rc = RegQueryValueExA(hkeyIfTypelib, NULL, NULL, NULL, (PBYTE)&szTypelibGuid[0], &cbValue);279 if (rc != ERROR_SUCCESS)280 cbValue = 0;281 szTypelibGuid[cbValue] = '\0';282 if (!isTypelibGuidToRemove(szTypelibGuid))283 {284 RegCloseKey(hkeyIfTypelib);285 continue;286 1176 } 287 288 char szTypelibVer[64];289 cbValue = sizeof(szTypelibVer) - 1;290 rc = RegQueryValueExA(hkeyIfTypelib, "Version", NULL, NULL, (PBYTE)&szTypelibVer[0], &cbValue);291 if (rc != ERROR_SUCCESS)292 cbValue = 0;293 szTypelibVer[cbValue] = '\0';294 295 RegCloseKey(hkeyIfTypelib);296 297 if (!isTypelibVersionToRemove(szTypelibVer))298 continue;299 300 301 /*302 * Ok, it's an orphaned VirtualBox interface. Delete it.303 */304 szCurNm[cbCurNm] = '\0';305 //RTAssertMsg2("Should delete HCR/Interface/%s\n", szCurNm);306 rc = SHDeleteKeyA(hkeyInterface, szCurNm);307 Assert(rc == ERROR_SUCCESS);308 1177 } 309 1178 … … 325 1194 { 326 1195 HKEY hkeyTyplib; 327 LONG rc = RegOpenKeyExA(hkeyClassesRoot, g_apszTypelibGuidKeys[i], NULL,1196 LONG rc = RegOpenKeyExA(hkeyClassesRoot, g_apszTypelibGuidKeys[i], 0, 328 1197 DELETE | KEY_ENUMERATE_SUB_KEYS | KEY_QUERY_VALUE, &hkeyTyplib); 329 1198 if (rc == ERROR_SUCCESS) … … 333 1202 { 334 1203 HKEY hkeyVer; 335 rc = RegOpenKeyExA(hkeyTyplib, g_apszTypelibVersions[iVer], NULL, KEY_READ, &hkeyVer);1204 rc = RegOpenKeyExA(hkeyTyplib, g_apszTypelibVersions[iVer], 0, KEY_READ, &hkeyVer); 336 1205 if (rc == ERROR_SUCCESS) 337 1206 { … … 350 1219 * Delete the type library. 351 1220 */ 352 //RTAssertMsg2("Should delete HCR\\%s\\%s\n", g_apszTypelibGuidKeys[i], g_apszTypelibVersions[iVer]);1221 RTAssertMsg2("Should delete HCR\\%s\\%s\n", g_apszTypelibGuidKeys[i], g_apszTypelibVersions[iVer]); 353 1222 rc = SHDeleteKeyA(hkeyTyplib, g_apszTypelibVersions[iVer]); 354 1223 Assert(rc == ERROR_SUCCESS); … … 377 1246 static void removeOldMess(void) 378 1247 { 1248 HKEY hkeyWow64; 1249 LONG rc; 1250 379 1251 /* 380 1252 * The standard location. … … 387 1259 * Wow64 if present. 388 1260 */ 389 HKEY hkeyWow64; 390 LONG rc = RegOpenKeyExA(HKEY_CLASSES_ROOT, "Wow6432Node", NULL, 391 DELETE | KEY_ENUMERATE_SUB_KEYS | KEY_QUERY_VALUE, &hkeyWow64); 1261 rc = RegOpenKeyExA(HKEY_CLASSES_ROOT, "Wow6432Node", 0, DELETE | KEY_ENUMERATE_SUB_KEYS | KEY_QUERY_VALUE, &hkeyWow64); 392 1262 if (rc == ERROR_SUCCESS) 393 1263 { -
trunk/src/VBox/Main/src-all/win/VBoxProxyStub.def
r49908 r59363 1 1 ; $Id$ 2 2 ;; @file 3 ; VBox CDLL Definition File.3 ; VBoxProxyStub DLL Definition File. 4 4 ; 5 5 6 6 ; 7 ; Copyright (C) 2006-201 3Oracle Corporation7 ; Copyright (C) 2006-2016 Oracle Corporation 8 8 ; 9 9 ; This file is part of VirtualBox Open Source Edition (OSE), as … … 23 23 DllRegisterServer PRIVATE 24 24 DllUnregisterServer PRIVATE 25 GetProxyDllInfo PRIVATE 25 26
Note:
See TracChangeset
for help on using the changeset viewer.