- Timestamp:
- Sep 13, 2016 2:53:10 PM (8 years ago)
- Location:
- trunk/src/VBox/Main
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/include/VirtualBoxClientImpl.h
r63643 r63814 67 67 static uint32_t g_cInstances; 68 68 69 #ifdef RT_OS_WINDOWS 70 virtual HRESULT i_investigateVirtualBoxObjectCreationFailure(HRESULT hrc); 71 #endif 72 69 73 static DECLCALLBACK(int) SVCWatcherThread(RTTHREAD ThreadSelf, void *pvUser); 70 74 -
trunk/src/VBox/Main/src-client/VirtualBoxClientImpl.cpp
r63639 r63814 28 28 #include <iprt/semaphore.h> 29 29 #include <iprt/cpp/utils.h> 30 #ifdef RT_OS_WINDOWS 31 # include <iprt/ldr.h> 32 # include <msi.h> 33 #endif 30 34 31 35 … … 91 95 rc = mData.m_pVirtualBox.createLocalObject(CLSID_VirtualBox); 92 96 if (FAILED(rc)) 97 #ifdef RT_OS_WINDOWS 98 throw i_investigateVirtualBoxObjectCreationFailure(rc); 99 #else 93 100 throw rc; 101 #endif 94 102 95 103 /* VirtualBox error return is postponed to method calls, fetch it. */ … … 156 164 return S_OK; 157 165 } 166 167 #ifdef RT_OS_WINDOWS 168 /** 169 * Looks into why we failed to create the VirtualBox object. 170 * 171 * @returns hrcCaller thru setError. 172 * @param hrcCaller The failure status code. 173 */ 174 HRESULT VirtualBoxClient::i_investigateVirtualBoxObjectCreationFailure(HRESULT hrcCaller) 175 { 176 /* 177 * First step is to try get an IUnknown interface of the VirtualBox object. 178 * 179 * This will succeed even when oleaut32.msm (see @bugref{8016}, @ticketref{12087}) 180 * is accidentally installed and messes up COM. It may also succeed when the COM 181 * registration is partially broken (though that's unlikely to happen these days). 182 */ 183 IUnknown *pUnknown = NULL; 184 HRESULT hrc = CoCreateInstance(CLSID_VirtualBox, NULL, CLSCTX_LOCAL_SERVER, IID_IUnknown, (void **)&pUnknown); 185 if (FAILED(hrc)) 186 { 187 if (hrc == hrcCaller) 188 return setError(hrcCaller, tr("Completely failed to instantiate CLSID_VirtualBox: %Rhrc"), hrcCaller); 189 return setError(hrcCaller, tr("Completely failed to instantiate CLSID_VirtualBox: %Rhrc & %Rhrc"), hrcCaller, hrc); 190 } 191 192 /* 193 * Try query the IVirtualBox interface (should fail), if it succeed we return 194 * straight away so we have more columns to spend on long messages below. 195 */ 196 IVirtualBox *pVirtualBox; 197 hrc = pUnknown->QueryInterface(IID_IVirtualBox, (void **)&pVirtualBox); 198 if (SUCCEEDED(hrc)) 199 { 200 pVirtualBox->Release(); 201 pUnknown->Release(); 202 return setError(hrcCaller, 203 tr("Failed to instantiate CLSID_VirtualBox the first time, but worked when checking out why ... weird")); 204 } 205 206 /* 207 * Check for oleaut32.msm traces in the registry. 208 */ 209 HKEY hKey; 210 LSTATUS lrc = RegOpenKeyExW(HKEY_CLASSES_ROOT, L"CLSID\\{00020420-0000-0000-C000-000000000046}\\InprocServer32", 211 0 /*fFlags*/, KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS | STANDARD_RIGHTS_READ, &hKey); 212 if (lrc == ERROR_SUCCESS) 213 { 214 wchar_t wszBuf[8192]; 215 DWORD cbBuf = sizeof(wszBuf) - sizeof(wchar_t); 216 DWORD dwType = 0; 217 lrc = RegQueryValueExW(hKey, L"InprocServer32", NULL /*pvReserved*/, &dwType, (BYTE *)&wszBuf[0], &cbBuf); 218 if (lrc == ERROR_SUCCESS) 219 { 220 wszBuf[cbBuf / sizeof(wchar_t)] = '\0'; 221 bool fSetError = false; 222 223 /* 224 * Try decode the string and improve the message. 225 */ 226 typedef UINT (WINAPI *PFNMSIDECOMPOSEDESCRIPTORW)(PCWSTR pwszDescriptor, 227 LPWSTR pwszProductCode /*[40]*/, 228 LPWSTR pwszFeatureId /*[40]*/, 229 LPWSTR pwszComponentCode /*[40]*/, 230 DWORD *poffArguments); 231 PFNMSIDECOMPOSEDESCRIPTORW pfnMsiDecomposeDescriptorW; 232 pfnMsiDecomposeDescriptorW = (PFNMSIDECOMPOSEDESCRIPTORW)RTLdrGetSystemSymbol("msi.dll", "MsiDecomposeDescriptorW"); 233 if ( pfnMsiDecomposeDescriptorW 234 && ( dwType == REG_SZ 235 || dwType == REG_MULTI_SZ)) 236 { 237 wchar_t wszProductCode[RTUUID_STR_LENGTH + 2 + 16] = { 0 }; 238 wchar_t wszFeatureId[RTUUID_STR_LENGTH + 2 + 16] = { 0 }; 239 wchar_t wszComponentCode[RTUUID_STR_LENGTH + 2 + 16] = { 0 }; 240 DWORD offArguments = ~(DWORD)0; 241 UINT uRc = pfnMsiDecomposeDescriptorW(wszBuf, wszProductCode, wszFeatureId, wszComponentCode, &offArguments); 242 if (uRc == 0) 243 { 244 /* 245 * Can we resolve the product code into a name? 246 */ 247 typedef UINT (WINAPI *PFNMSIOPENPRODUCTW)(PCWSTR, MSIHANDLE *); 248 PFNMSIOPENPRODUCTW pfnMsiOpenProductW; 249 pfnMsiOpenProductW = (PFNMSIOPENPRODUCTW)RTLdrGetSystemSymbol("msi.dll", "MsiOpenProductW"); 250 251 typedef UINT (WINAPI *PFNMSICLOSEHANDLE)(MSIHANDLE); 252 PFNMSICLOSEHANDLE pfnMsiCloseHandle; 253 pfnMsiCloseHandle = (PFNMSICLOSEHANDLE)RTLdrGetSystemSymbol("msi.dll", "MsiCloseHandle"); 254 255 typedef UINT (WINAPI *PFNGETPRODUCTPROPERTYW)(MSIHANDLE, PCWSTR, PWSTR, PDWORD); 256 PFNGETPRODUCTPROPERTYW pfnMsiGetProductPropertyW; 257 pfnMsiGetProductPropertyW = (PFNGETPRODUCTPROPERTYW)RTLdrGetSystemSymbol("msi.dll", "MsiGetProductPropertyW"); 258 if ( pfnMsiGetProductPropertyW 259 && pfnMsiCloseHandle 260 && pfnMsiOpenProductW) 261 { 262 MSIHANDLE hMsi = 0; 263 uRc = pfnMsiOpenProductW(wszProductCode, &hMsi); 264 if (uRc == 0) 265 { 266 static wchar_t const * const s_apwszProps[] = 267 { 268 INSTALLPROPERTY_INSTALLEDPRODUCTNAME, 269 INSTALLPROPERTY_PRODUCTNAME, 270 INSTALLPROPERTY_PACKAGENAME, 271 }; 272 273 wchar_t wszProductName[1024]; 274 DWORD cwcProductName; 275 unsigned i = 0; 276 do 277 { 278 cwcProductName = RT_ELEMENTS(wszProductName) - 1; 279 uRc = pfnMsiGetProductPropertyW(hMsi, s_apwszProps[i], wszProductName, &cwcProductName); 280 } 281 while ( ++i < RT_ELEMENTS(s_apwszProps) 282 && ( uRc != 0 283 || cwcProductName < 2 284 || cwcProductName >= RT_ELEMENTS(wszProductName)) ); 285 uRc = pfnMsiCloseHandle(hMsi); 286 if (uRc == 0 && cwcProductName >= 2) 287 { 288 wszProductName[RT_MIN(cwcProductName, RT_ELEMENTS(wszProductName) - 1)] = '\0'; 289 setError(hrcCaller, 290 tr("Failed to instantiate CLSID_VirtualBox w/ IVirtualBox, but CLSID_VirtualBox w/ IUnknown works.\n" 291 "PSDispatch looks broken by the '%ls' (%ls) program, suspecting that it features the broken oleaut32.msm module as component %ls.\n" 292 "\n" 293 "We suggest you try uninstall '%ls'.\n" 294 "\n" 295 "See also https://support.microsoft.com/en-us/kb/316911 "), 296 wszProductName, wszProductCode, wszComponentCode, wszProductName); 297 fSetError = true; 298 } 299 } 300 } 301 302 /* MSI uses COM and may mess up our stuff. So, we wait with the fallback till afterwards in this case. */ 303 if (!fSetError) 304 { 305 setError(hrcCaller, 306 tr("Failed to instantiate CLSID_VirtualBox w/ IVirtualBox, CLSID_VirtualBox w/ IUnknown works.\n" 307 "PSDispatch looks broken by installer %ls featuring the broken oleaut32.msm module as component %ls.\n" 308 "\n" 309 "See also https://support.microsoft.com/en-us/kb/316911 "), 310 wszProductCode, wszComponentCode); 311 fSetError = true; 312 } 313 } 314 } 315 if (!fSetError) 316 setError(hrcCaller, tr("Failed to instantiate CLSID_VirtualBox w/ IVirtualBox, CLSID_VirtualBox w/ IUnknown works.\n" 317 "PSDispatch looks broken by some installer featuring the broken oleaut32.msm module as a component.\n" 318 "\n" 319 "See also https://support.microsoft.com/en-us/kb/316911 ")); 320 } 321 else if (lrc == ERROR_FILE_NOT_FOUND) 322 setError(hrcCaller, tr("Failed to instantiate CLSID_VirtualBox w/ IVirtualBox, but CLSID_VirtualBox w/ IUnknown works.\n" 323 "PSDispatch looks fine. Weird")); 324 else 325 setError(hrcCaller, tr("Failed to instantiate CLSID_VirtualBox w/ IVirtualBox, but CLSID_VirtualBox w/ IUnknown works.\n" 326 "Checking out PSDispatch registration ended with error: %u (%#x)"), lrc, lrc); 327 RegCloseKey(hKey); 328 } 329 330 pUnknown->Release(); 331 return hrcCaller; 332 } 333 #endif /* RT_OS_WINDOWS */ 158 334 159 335 /**
Note:
See TracChangeset
for help on using the changeset viewer.