Changeset 2672
- Timestamp:
- 05/16/07 17:31:49 (2 years ago)
- Files:
-
- trunk/include/VBox/com/ErrorInfo.h (modified) (9 diffs)
- trunk/include/VBox/com/com.h (modified) (1 diff)
- trunk/src/VBox/Main/ConsoleImpl.cpp (modified) (7 diffs)
- trunk/src/VBox/Main/MachineImpl.cpp (modified) (7 diffs)
- trunk/src/VBox/Main/VirtualBoxBase.cpp (modified) (3 diffs)
- trunk/src/VBox/Main/VirtualBoxErrorInfoImpl.cpp (modified) (4 diffs)
- trunk/src/VBox/Main/glue/ErrorInfo.cpp (modified) (9 diffs)
- trunk/src/VBox/Main/glue/com.cpp (modified) (6 diffs)
- trunk/src/VBox/Main/idl/VirtualBox.xidl (modified) (1 diff)
- trunk/src/VBox/Main/include/VirtualBoxBase.h (modified) (8 diffs)
- trunk/src/VBox/Main/include/VirtualBoxErrorInfoImpl.h (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/include/VBox/com/ErrorInfo.h
r1 r2672 28 28 #include "VBox/com/Guid.h" 29 29 #include "VBox/com/assert.h" 30 31 #include <iprt/memory> // for auto_copy_ptr 30 32 31 33 struct IProgress; … … 102 104 * pointer available. 103 105 */ 104 explicit ErrorInfo() : 105 mIsBasicAvailable (false), mIsFullAvailable (false), mResultCode (S_OK) 106 { init(); } 106 explicit ErrorInfo() 107 : mIsBasicAvailable (false), mIsFullAvailable (false) 108 , mResultCode (S_OK) 109 { init(); } 107 110 108 111 /** … … 118 121 * error 119 122 */ 120 template <class I> ErrorInfo (I *aPtr) : 121 mIsBasicAvailable (false), mIsFullAvailable (false), mResultCode (S_OK) 122 { init (aPtr, COM_IIDOF(I)); } 123 template <class I> ErrorInfo (I *aPtr) 124 : mIsBasicAvailable (false), mIsFullAvailable (false) 125 , mResultCode (S_OK) 126 { init (aPtr, COM_IIDOF(I)); } 123 127 124 128 /** … … 129 133 * an error 130 134 */ 131 template <class I> ErrorInfo (const ComPtr <I> &aPtr) : 132 mIsBasicAvailable (false), mIsFullAvailable (false), mResultCode (S_OK) 133 { init (static_cast <I*> (aPtr), COM_IIDOF(I)); } 135 template <class I> ErrorInfo (const ComPtr <I> &aPtr) 136 : mIsBasicAvailable (false), mIsFullAvailable (false) 137 , mResultCode (S_OK) 138 { init (static_cast <I*> (aPtr), COM_IIDOF(I)); } 134 139 135 140 /** Specialization for the IVirtualBoxErrorInfo smart pointer */ 136 ErrorInfo (const ComPtr <IVirtualBoxErrorInfo> &aPtr) : 137 mIsBasicAvailable (false), mIsFullAvailable (false), mResultCode (S_OK) 138 { init (aPtr); } 141 ErrorInfo (const ComPtr <IVirtualBoxErrorInfo> &aPtr) 142 : mIsBasicAvailable (false), mIsFullAvailable (false) 143 , mResultCode (S_OK) 144 { init (aPtr); } 139 145 140 146 /** … … 146 152 * holds error info to be fetched by this instance 147 153 */ 148 ErrorInfo (IVirtualBoxErrorInfo *aInfo) : 149 mIsBasicAvailable (false), mIsFullAvailable (false), mResultCode (S_OK) 150 { init (aInfo); } 151 152 ~ErrorInfo(); 154 ErrorInfo (IVirtualBoxErrorInfo *aInfo) 155 : mIsBasicAvailable (false), mIsFullAvailable (false) 156 , mResultCode (S_OK) 157 { init (aInfo); } 158 159 virtual ~ErrorInfo(); 153 160 154 161 /** … … 201 208 202 209 /** 210 * Returns the next error information object or @c NULL if there is none. 211 */ 212 const ErrorInfo *getNext() const { return mNext.get(); } 213 214 /** 203 215 * Returns the name of the interface that defined the error 204 216 */ … … 233 245 protected: 234 246 235 ErrorInfo (bool dummy) : 236 mIsBasicAvailable (false), mIsFullAvailable (false), mResultCode (S_OK) 237 {} 238 239 void init(); 240 void init (IUnknown *i, const GUID &iid); 241 void init (IVirtualBoxErrorInfo *info); 242 243 private: 244 245 bool mIsBasicAvailable; 246 bool mIsFullAvailable; 247 ErrorInfo (bool aDummy) 248 : mIsBasicAvailable (false), mIsFullAvailable (false) 249 , mResultCode (S_OK) 250 {} 251 252 void init (bool aKeepObj = false); 253 void init (IUnknown *aUnk, const GUID &aIID, bool aKeepObj = false); 254 void init (IVirtualBoxErrorInfo *aInfo); 255 256 bool mIsBasicAvailable : 1; 257 bool mIsFullAvailable : 1; 247 258 248 259 HRESULT mResultCode; … … 251 262 Bstr mText; 252 263 264 cppx::auto_copy_ptr <ErrorInfo> mNext; 265 253 266 Bstr mInterfaceName; 254 267 Guid mCalleeIID; 255 268 Bstr mCalleeName; 269 270 ComPtr <IUnknown> mErrorInfo; 256 271 }; 257 272 258 273 /** 259 * A convenience subclass of ErrorInfo ,that, given an IProgress interface274 * A convenience subclass of ErrorInfo that, given an IProgress interface 260 275 * pointer, reads its errorInfo attribute and uses the returned 261 276 * IVirtualBoxErrorInfo instance to construct itself. … … 277 292 }; 278 293 294 /** 295 * A convenience subclass of ErrorInfo that allows to preserve the current 296 * error info. Instances of this class fetch an error info object set on the 297 * current thread and keep a reference to it, which allows to restore it 298 * later using the #restore() method. This is useful to preserve error 299 * information returned by some method for the duration of making another COM 300 * call that may set its own error info and overwrite the existing 301 * one. Preserving and restoring error information makes sense when some 302 * method wants to return error information set by other call as its own 303 * error information while it still needs to make another call before return. 304 * 305 * The usage pattern is: 306 * <code> 307 * rc = foo->method(); 308 * if (FAILED (rc)) 309 * { 310 * ErrorInfoKeeper eik; 311 * ... 312 * // bar may return error info as well 313 * bar->method(); 314 * ... 315 * // restore error info from foo to return it to the caller 316 * eik.restore(); 317 * return rc; 318 * } 319 * </code> 320 */ 321 class ErrorInfoKeeper : public ErrorInfo 322 { 323 public: 324 325 /** Constructs a new instance that will fetch the current error info. */ 326 ErrorInfoKeeper() : ErrorInfo (false), mForgot (false) 327 { init (true /* aKeepObj */); } 328 329 /** 330 * Destroys this instance and automatically calls #restore() which will 331 * either restorr error info fetched by the constructor or do nothing 332 * if #forget() was called before destruction. */ 333 ~ErrorInfoKeeper() { if (!mForgot) restore(); } 334 335 /** 336 * Restores error info fetched by the constructor and forgets it 337 * afterwards. 338 * 339 * @return COM result of the restore operation. 340 */ 341 HRESULT restore(); 342 343 /** 344 * Forgets error info fetched by the constructor which prevents it from 345 * being restored by #restore() or by the destructor. 346 */ 347 void forget() { mForgot = 0; } 348 349 private: 350 351 bool mForgot : 1; 352 }; 353 279 354 }; // namespace com 280 355 trunk/include/VBox/com/com.h
r1 r2672 38 38 39 39 /** 40 * Shut downsthe COM runtime.40 * Shuts down the COM runtime. 41 41 * Must be called on every thread before termination. 42 * No anyCOM calls may be made after this method returns.42 * No COM calls may be made after this method returns. 43 43 */ 44 44 void Shutdown(); 45 46 /** 47 * Resolves a given interface ID to a string containing the interface name. 48 * If, for some reason, the given IID cannot be resolved to a name, a NULL 49 * string is returned. A non-NULL string returned by this funciton must be 50 * freed using SysFreeString(). 51 * 52 * @param aIID ID of the interface to get a name for 53 * @param aName Resolved interface name or @c NULL on error 54 */ 55 void GetInterfaceNameByIID (const GUID &aIID, BSTR *aName); 45 56 46 57 }; // namespace com trunk/src/VBox/Main/ConsoleImpl.cpp
r2651 r2672 1785 1785 if (FAILED (rc) && !taskCreationFailed) 1786 1786 { 1787 /* fetch anyexisting error info */1788 ErrorInfo ei;1787 /* preserve existing error info */ 1788 ErrorInfoKeeper eik; 1789 1789 1790 1790 if (beganSavingState) … … 1807 1807 else 1808 1808 setMachineStateLocally (lastMachineState); 1809 1810 /* restore fetched error info */1811 setError (ei);1812 1809 } 1813 1810 … … 2340 2337 if (FAILED (rc) && !taskCreationFailed) 2341 2338 { 2342 /* fetch anyexisting error info */2343 ErrorInfo ei;2339 /* preserve existing error info */ 2340 ErrorInfoKeeper eik; 2344 2341 2345 2342 if (beganTakingSnapshot && takingSnapshotOnline) … … 2363 2360 else 2364 2361 setMachineStateLocally (lastMachineState); 2365 2366 /* restore fetched error info */2367 setError (ei);2368 2362 } 2369 2363 … … 6795 6789 if (FAILED (hrc) || VBOX_FAILURE (vrc)) 6796 6790 { 6797 /* preserve the currenterror info */6798 ErrorInfo ei;6791 /* preserve existing error info */ 6792 ErrorInfoKeeper eik; 6799 6793 6800 6794 /* … … 6804 6798 HRESULT hrc2 = console->powerDown(); 6805 6799 AssertComRC (hrc2); 6806 6807 setError (ei);6808 6800 } 6809 6801 } … … 6860 6852 */ 6861 6853 6862 /* preserve the currenterror info */6863 ErrorInfo ei;6854 /* preserve existing error info */ 6855 ErrorInfoKeeper eik; 6864 6856 6865 6857 Assert (console->mpVM == NULL); 6866 6858 vmstateChangeCallback (NULL, VMSTATE_TERMINATED, VMSTATE_CREATING, 6867 6859 console); 6868 setError (ei);6869 6860 } 6870 6861 trunk/src/VBox/Main/MachineImpl.cpp
r2656 r2672 8951 8951 } 8952 8952 8953 /* fetch the currenterror info */8954 ErrorInfo mergeEi;8953 /* preserve existing error info */ 8954 ErrorInfoKeeper mergeEik; 8955 8955 HRESULT mergeRc = rc; 8956 8956 … … 9026 9026 while (0); 9027 9027 9028 /* restore the merge error if any */ 9028 /* restore the merge error if any (ErrorInfo will be restored 9029 * automatically) */ 9029 9030 if (FAILED (mergeRc)) 9030 {9031 9031 rc = mergeRc; 9032 setError (mergeEi);9033 }9034 9032 } 9035 9033 while (0); … … 9039 9037 if (!aTask.subTask) 9040 9038 { 9041 /* save currenterror info */9042 ErrorInfo ei;9039 /* preserve existing error info */ 9040 ErrorInfoKeeper eik; 9043 9041 9044 9042 /* restore the machine state */ … … 9055 9053 true /* aInformCallbacksAnyway */); 9056 9054 } 9057 9058 /* restore current error info */9059 setError (ei);9060 9055 } 9061 9056 … … 9187 9182 { 9188 9183 /* here we can still safely rollback, so do it */ 9189 ErrorInfo ei; 9184 /* preserve existing error info */ 9185 ErrorInfoKeeper eik; 9190 9186 /* undo all changes */ 9191 9187 rollback (false /* aNotify */); 9192 setError (ei);9193 9188 break; 9194 9189 } … … 9306 9301 if (FAILED (rc)) 9307 9302 { 9308 ErrorInfo ei; 9303 /* preserve existing error info */ 9304 ErrorInfoKeeper eik; 9309 9305 9310 9306 if (!stateRestored) … … 9328 9324 saveSettings(); 9329 9325 } 9330 9331 setError (ei);9332 9326 } 9333 9327 trunk/src/VBox/Main/VirtualBoxBase.cpp
r1 r2672 641 641 //////////////////////////////////////////////////////////////////////////////// 642 642 643 /** 644 * Sets error info for the current thread. This is an internal function that 645 * gets eventually called by all public variants. If @a aPreserve is 646 * @c true, then the current error info object set on the thread before this 647 * method is called will be preserved in the IVirtualBoxErrorInfo::next 648 * attribute of the new error info object that will be then set as the 649 * current error info object. 650 */ 643 651 // static 644 HRESULT VirtualBoxSupportErrorInfoImplBase::setError ( 645 HRESULT resultCode, const GUID &iid, 646 const Bstr &component, 647 const Bstr &text) 648 { 649 LogRel (("ERROR [COM]: rc=%#08x IID={%Vuuid} component={%ls} text={%ls}\n", 650 resultCode, &iid, component.raw(), text.raw())); 652 HRESULT VirtualBoxSupportErrorInfoImplBase::setErrorInternal ( 653 HRESULT aResultCode, const GUID &aIID, 654 const Bstr &aComponent, const Bstr &aText, 655 bool aPreserve) 656 { 657 LogRel (("ERROR [COM]: aRC=%#08x aIID={%Vuuid} aComponent={%ls} aText={%ls} " 658 "aPreserve=%RTbool\n", 659 aResultCode, &aIID, aComponent.raw(), aText.raw(), aPreserve)); 651 660 652 661 /* these are mandatory, others -- not */ 653 Assert (FAILED (resultCode));654 Assert (!text.isEmpty());655 if (SUCCEEDED (resultCode) || text.isEmpty()) 656 return E_FAIL;657 658 ComObjPtr <VirtualBoxErrorInfo> info;659 HRESULT rc = info.createObject();660 if (SUCCEEDED (rc))661 {662 info->init (resultCode, iid, component, text);662 AssertReturn (FAILED (aResultCode), E_FAIL); 663 AssertReturn (!aText.isEmpty(), E_FAIL); 664 665 HRESULT rc = S_OK; 666 667 do 668 { 669 ComObjPtr <VirtualBoxErrorInfo> info; 670 rc = info.createObject(); 671 CheckComRCBreakRC (rc); 663 672 664 673 #if defined (__WIN__) 674 675 ComPtr <IVirtualBoxErrorInfo> curInfo; 676 if (aPreserve) 677 { 678 /* get the current error info if any */ 679 ComPtr <IErrorInfo> err; 680 rc = ::GetErrorInfo (0, err.asOutParam()); 681 CheckComRCBreakRC (rc); 682 rc = err.queryInterfaceTo (curInfo.asOutParam()); 683 if (FAILED (rc)) 684 { 685 /* create a IVirtualBoxErrorInfo wrapper for the native 686 * IErrorInfo object */ 687 ComObjPtr <VirtualBoxErrorInfo> wrapper; 688 rc = wrapper.createObject(); 689 if (SUCCEEDED (rc)) 690 { 691 rc = wrapper->init (err); 692 if (SUCCEEDED (rc)) 693 curInfo = wrapper; 694 } 695 } 696 } 697 /* On failure, curInfo will stay null */ 698 Assert (SUCCEEDED (rc) || curInfo.isNull()); 699 700 /* set the current error info and preserve the previous one if any */ 701 rc = info->init (aResultCode, aIID, aComponent, aText, curInfo); 702 CheckComRCBreakRC (rc); 665 703 666 704 ComPtr <IErrorInfo> err; … … 677 715 nsCOMPtr <nsIExceptionManager> em; 678 716 rc = es->GetCurrentExceptionManager (getter_AddRefs (em)); 679 if (NS_SUCCEEDED (rc)) 717 CheckComRCBreakRC (rc); 718 719 ComPtr <IVirtualBoxErrorInfo> curInfo; 720 if (aPreserve) 680 721 { 722 /* get the current error info if any */ 681 723 ComPtr <nsIException> ex; 682 rc = info.queryInterfaceTo (ex.asOutParam()); 683 if (SUCCEEDED (rc)) 684 rc = em->SetCurrentException (ex); 724 rc = em->GetCurrentException (ex.asOutParam()); 725 CheckComRCBreakRC (rc); 726 rc = ex.queryInterfaceTo (curInfo.asOutParam()); 727 if (FAILED (rc)) 728 { 729 /* create a IVirtualBoxErrorInfo wrapper for the native 730 * nsIException object */ 731 ComObjPtr <VirtualBoxErrorInfo> wrapper; 732 rc = wrapper.createObject(); 733 if (SUCCEEDED (rc)) 734 { 735 rc = wrapper->init (ex); 736 if (SUCCEEDED (rc)) 737 curInfo = wrapper; 738 } 739 } 685 740 } 741 /* On failure, curInfo will stay null */ 742 Assert (SUCCEEDED (rc) || curInfo.isNull()); 743 744 /* set the current error info and preserve the previous one if any */ 745 rc = info->init (aResultCode, aIID, aComponent, aText, curInfo); 746 CheckComRCBreakRC (rc); 747 748 ComPtr <nsIException> ex; 749 rc = info.queryInterfaceTo (ex.asOutParam()); 750 if (SUCCEEDED (rc)) 751 rc = em->SetCurrentException (ex); 686 752 } 687 753 else if (rc == NS_ERROR_UNEXPECTED) … … 705 771 #endif // !defined (__WIN__) 706 772 } 773 while (0); 707 774 708 775 AssertComRC (rc); 709 776 710 return SUCCEEDED (rc) ? resultCode : rc; 711 } 712 713 // static 714 HRESULT VirtualBoxSupportErrorInfoImplBase::setError ( 715 HRESULT resultCode, const GUID &iid, 716 const Bstr &component, 717 const char *text, va_list args) 718 { 719 return VirtualBoxSupportErrorInfoImplBase::setError ( 720 resultCode, iid, component, Utf8StrFmt (text, args)); 777 return SUCCEEDED (rc) ? aResultCode : rc; 721 778 } 722 779 trunk/src/VBox/Main/VirtualBoxErrorInfoImpl.cpp
r2463 r2672 26 26 //////////////////////////////////////////////////////////////////////////////// 27 27 28 voidVirtualBoxErrorInfo::init (HRESULT aResultCode, const GUID &aIID,29 const BSTR aComponent, const BSTR aText,30 IVirtualBoxErrorInfo *aNext)28 HRESULT VirtualBoxErrorInfo::init (HRESULT aResultCode, const GUID &aIID, 29 const BSTR aComponent, const BSTR aText, 30 IVirtualBoxErrorInfo *aNext) 31 31 { 32 32 mResultCode = aResultCode; … … 35 35 mText = aText; 36 36 mNext = aNext; 37 38 return S_OK; 37 39 } 38 40 … … 87 89 #if defined (__WIN__) 88 90 91 /** 92 * Initializes itself by fetching error information from the given error info 93 * object. 94 */ 95 HRESULT VirtualBoxErrorInfo::init (IErrorInfo *aInfo) 96 { 97 AssertReturn (aInfo, E_FAIL); 98 99 HRESULT rc = S_OK; 100 101 /* We don't return a failure if talking to IErrorInfo fails below to 102 * protect ourselves from bad IErrorInfo implementations (the 103 * corresponding fields will simply remain null in this case). */ 104 105 mResultCode = S_OK; 106 rc = aInfo->GetGUID (mIID.asOutParam()); 107 AssertComRC (rc); 108 rc = aInfo->GetSource (mComponent.asOutParam()); 109 AssertComRC (rc); 110 rc = aInfo->GetDescription (mText.asOutParam()); 111 AssertComRC (rc); 112 113 return S_OK; 114 } 115 89 116 // IErrorInfo methods 90 117 //////////////////////////////////////////////////////////////////////////////// … … 116 143 117 144 #else // !defined (__WIN__) 145 146 /** 147 * Initializes itself by fetching error information from the given error info 148 * object. 149 */ 150 HRESULT VirtualBoxErrorInfo::init (nsIException *aInfo) 151 { 152 AssertReturn (aInfo, E_FAIL); 153 154 HRESULT rc = S_OK; 155 156 /* We don't return a failure if talking to nsIException fails below to 157 * protect ourselves from bad nsIException implementations (the 158 * corresponding fields will simply remain null in this case). */ 159 160 rc = aInfo->GetResult (&mResultCode); 161 AssertComRC (rc); 162 Utf8Str message; 163 rc = aInfo->GetMessage (message.asOutParam()); 164 AssertComRC (rc); 165 mText = message; 166 167 return S_OK; 168 } 118 169 119 170 // nsIException methods trunk/src/VBox/Main/glue/ErrorInfo.cpp
r1959 r2672 20 20 */ 21 21 22 #if defined (__WIN__)23 24 #else // !defined (__WIN__)22 #if !defined (VBOX_WITH_XPCOM) 23 24 #else 25 25 26 26 #include <nsIServiceManager.h> … … 28 28 #include <nsCOMPtr.h> 29 29 30 #include <nsIInterfaceInfo.h> 31 #include <nsIInterfaceInfoManager.h> 32 33 #endif // !defined (__WIN__) 34 30 #endif 35 31 36 32 #include "VBox/com/VirtualBox.h" 37 33 #include "VBox/com/ErrorInfo.h" 38 34 #include "VBox/com/assert.h" 35 #include "VBox/com/com.h" 39 36 40 37 #include <iprt/stream.h> 41 38 #include <iprt/string.h> 39 42 40 #include <VBox/err.h> 43 41 44 /**45 * Resolves a given interface ID to a string containint interface name.46 * If, for some reason, the given IID cannot be resolved to a name,47 * a NULL string is returned. A non-NULL interface name must be freed48 * using SysFreeString().49 */50 static void GetInterfaceNameByIID (const GUID &id, BSTR *name)51 {52 Assert (name);53 if (!name)54 return;55 56 *name = NULL;57 58 #if defined (__WIN__)59 60 LONG rc;61 LPOLESTR iidStr = NULL;62 if (StringFromIID (id, &iidStr) == S_OK)63 {64 HKEY ifaceKey;65 rc = RegOpenKeyExW (HKEY_CLASSES_ROOT, L"Interface", 0, KEY_QUERY_VALUE, &ifaceKey);66 if (rc == ERROR_SUCCESS)67 {68 HKEY iidKey;69 rc = RegOpenKeyExW (ifaceKey, iidStr, 0, KEY_QUERY_VALUE, &iidKey);70 if (rc == ERROR_SUCCESS)71 {72 // determine the size and type73 DWORD sz, type;74 rc = RegQueryValueExW (iidKey, NULL, NULL, &type, NULL, &sz);75 if (rc == ERROR_SUCCESS && type == REG_SZ)76 {77 // query the value to BSTR78 *name = SysAllocStringLen (NULL, (sz + 1) / sizeof (TCHAR) + 1);79 rc = RegQueryValueExW (iidKey, NULL, NULL, NULL, (LPBYTE) *name, &sz);80 if (rc != ERROR_SUCCESS)81 {82 SysFreeString (*name);83 name = NULL;84 }85 }86 RegCloseKey (iidKey);87 }88 RegCloseKey (ifaceKey);89 }90 CoTaskMemFree (iidStr);91 }92 93 #else94 95 nsresult rv;96 nsCOMPtr <nsIInterfaceInfoManager> iim =97 do_GetService (NS_INTERFACEINFOMANAGER_SERVICE_CONTRACTID, &rv);98 if (NS_SUCCEEDED (rv))99 {100 nsCOMPtr <nsIInterfaceInfo> iinfo;101 rv = iim->GetInfoForIID (&id, getter_AddRefs (iinfo));102 if (NS_SUCCEEDED (rv))103 {104 const char *iname = NULL;105 iinfo->GetNameShared (&iname);106 char *utf8IName = NULL;107 if (VBOX_SUCCESS (RTStrCurrentCPToUtf8 (&utf8IName, iname)))108 {109 PRTUCS2 ucs2IName = NULL;110 if (VBOX_SUCCESS (RTStrUtf8ToUcs2 (&ucs2IName, utf8IName)))111 {112 *name = SysAllocString ((OLECHAR *) ucs2IName);113 RTStrUcs2Free (ucs2IName);114 }115 RTStrFree (utf8IName);116 }117 }118 }119 120 #endif121 }122 123 124 42 namespace com 125 43 { 126 44 127 // IErrorInfo class45 // ErrorInfo class 128 46 //////////////////////////////////////////////////////////////////////////////// 129 47 130 void ErrorInfo::init ( )48 void ErrorInfo::init (bool aKeepObj /* = false */) 131 49 { 132 50 HRESULT rc = E_FAIL; 133 51 134 #if defined (__WIN__)52 #if !defined (VBOX_WITH_XPCOM) 135 53 136 54 ComPtr <IErrorInfo> err; … … 138 56 if (rc == S_OK && err) 139 57 { 58 if (aKeepObj) 59 mErrorInfo = err; 60 140 61 ComPtr <IVirtualBoxErrorInfo> info; 141 62 rc = err.queryInterfaceTo (info.asOutParam()); … … 165 86 } 166 87 167 #else // !defined ( __WIN__)88 #else // !defined (VBOX_WITH_XPCOM) 168 89 169 90 nsCOMPtr <nsIExceptionService> es; … … 179 100 if (NS_SUCCEEDED (rc) && ex) 180 101 { 102 if (aKeepObj) 103 mErrorInfo = ex; 104 181 105 ComPtr <IVirtualBoxErrorInfo> info; 182 106 rc = ex.queryInterfaceTo (info.asOutParam()); … … 213 137 AssertComRC (rc); 214 138 215 #endif // !defined ( __WIN__)216 } 217 218 void ErrorInfo::init (IUnknown * i, const GUID &iid)219 { 220 Assert ( i);221 if (! i)139 #endif // !defined (VBOX_WITH_XPCOM) 140 } 141 142 void ErrorInfo::init (IUnknown *aI, const GUID &aIID, bool aKeepObj /* = false */) 143 { 144 Assert (aI); 145 if (!aI) 222 146 return; 223 147 224 #if defined (__WIN__)225 226 ComPtr <IUnknown> iface = i;148 #if !defined (VBOX_WITH_XPCOM) 149 150 ComPtr <IUnknown> iface = aI; 227 151 ComPtr <ISupportErrorInfo> serr; 228 152 HRESULT rc = iface.queryInterfaceTo (serr.asOutParam()); 229 153 if (SUCCEEDED (rc)) 230 154 { 231 rc = serr->InterfaceSupportsErrorInfo ( iid);155 rc = serr->InterfaceSupportsErrorInfo (aIID); 232 156 if (SUCCEEDED (rc)) 233 init ();234 } 235 236 #else // !defined (__WIN__)237 238 init ();239 240 #endif // !defined (__WIN__)157 init (aKeepObj); 158 } 159 160 #else 161 162 init (aKeepObj); 163 164 #endif 241 165 242 166 if (mIsBasicAvailable) 243 167 { 244 mCalleeIID = iid;245 GetInterfaceNameByIID ( iid, mCalleeName.asOutParam());168 mCalleeIID = aIID; 169 GetInterfaceNameByIID (aIID, mCalleeName.asOutParam()); 246 170 } 247 171 } … … 270 194 271 195 rc = info->COMGETTER(Text) (mText.asOutParam()); 196 gotSomething |= SUCCEEDED (rc); 197 gotAll &= SUCCEEDED (rc); 198 199 ComPtr <IVirtualBoxErrorInfo> next; 200 rc = info->COMGETTER(Next) (next.asOutParam()); 201 if (SUCCEEDED (rc) && !next.isNull()) 202 { 203 mNext.reset (new ErrorInfo (next)); 204 Assert (mNext.get()); 205 if (!mNext.get()) 206 rc = E_OUTOFMEMORY; 207 } 208 else 209 mNext.reset(); 272 210 gotSomething |= SUCCEEDED (rc); 273 211 gotAll &= SUCCEEDED (rc); … … 300 238 } 301 239 302 // IErrorInfo class 240 /** 241 * Sets the given error info object for the current thread. If @a aPreserve 242 * is @c true, then the current error info set on the thread before this 243 * method is called will be preserved in the IVirtualBoxErrorInfo::next 244 * attribute of the new error info object that will be then set as the 245 * current error info object. 246 */ 247 248 //static 249 HRESULT setError (IVirtualBoxErrorInfo *aInfo); 250 251 // ProgressErrorInfo class 303 252 //////////////////////////////////////////////////////////////////////////////// 304 253 305 254 ProgressErrorInfo::ProgressErrorInfo (IProgress *progress) : 306 ErrorInfo ( true)255 ErrorInfo (false /* aDummy */) 307 256 { 308 257 Assert (progress); … … 316 265 } 317 266 267 // ErrorInfoKeeper class 268 //////////////////////////////////////////////////////////////////////////////// 269 270 HRESULT ErrorInfoKeeper::restore() 271 { 272 if (mForgot) 273 return S_OK; 274 275 HRESULT rc = S_OK; 276 277 #if !defined (VBOX_WITH_XPCOM) 278 279 ComPtr <IErrorInfo> err; 280 if (!mErrorInfo.isNull()) 281 { 282 rc = mErrorInfo.queryInterfaceTo (err.asOutParam()); 283 AssertComRC (rc); 284 } 285 rc = ::SetErrorInfo (0, err); 286 287 #else // !defined (VBOX_WITH_XPCOM) 288 289 nsCOMPtr <nsIExceptionService> es; 290 es = do_GetService (NS_EXCEPTIONSERVICE_CONTRACTID, &rc); 291 if (NS_SUCCEEDED (rc)) 292 { 293 nsCOMPtr <nsIExceptionManager> em; 294 rc = es->GetCurrentExceptionManager (getter_AddRefs (em)); 295 if (NS_SUCCEEDED (rc)) 296 { 297 ComPtr <nsIException> ex; 298 if (!mErrorInfo.isNull()) 299 { 300 rc = mErrorInfo.queryInterfaceTo (ex.asOutParam()); 301 AssertComRC (rc); 302 } 303 rc = em->SetCurrentException (ex); 304 } 305 } 306 307 #endif // !defined (VBOX_WITH_XPCOM) 308 309 if (SUCCEEDED (rc)) 310 { 311 mErrorInfo.setNull(); 312 mForgot = true; 313 } 314 315 return rc; 316 } 317 318 318 }; // namespace com 319 319 trunk/src/VBox/Main/glue/com.cpp
r1 r2672 20 20 */ 21 21 22 #if defined (__WIN__)22 #if !defined (VBOX_WITH_XPCOM) 23 23 24 24 #include <objbase.h> 25 25 26 #else // !defined (__WIN__)26 #else 27 27 28 28 #include <stdlib.h> … … 36 36 #include <nsEventQueueUtils.h> 37 37 38 #endif // !defined (__WIN__) 38 #include <nsIInterfaceInfo.h> 39 #include <nsIInterfaceInfoManager.h> 40 41 #endif 42 43 #include <iprt/string.h> 44 #include <VBox/err.h> 39 45 40 46 #include "VBox/com/com.h" … … 48 54 HRESULT rc = E_FAIL; 49 55 50 #if defined (__WIN__) 56 #if !defined (VBOX_WITH_XPCOM) 57 51 58 rc = CoInitializeEx (NULL, COINIT_MULTITHREADED | 52 59 COINIT_DISABLE_OLE1DDE | 53 60 COINIT_SPEED_OVER_MEMORY); 54 #else 55 /* 56 * Set VBOX_XPCOM_HOME if not present 57 */61 62 #else 63 64 /* Set VBOX_XPCOM_HOME if not present */ 58 65 if (!getenv("VBOX_XPCOM_HOME")) 59 66 { … … 82 89 } 83 90 } 91 84 92 #endif 85 93 … … 91 99 void Shutdown() 92 100 { 93 #if defined (__WIN__) 101 #if !defined (VBOX_WITH_XPCOM) 102 94 103 CoUninitialize(); 95 #else 104 105 #else 106 96 107 nsCOMPtr <nsIEventQueue> eventQ; 97 108 nsresult rc = NS_GetMainEventQ (getter_AddRefs (eventQ)); … … 100 111 BOOL isOnMainThread = FALSE; 101 112 eventQ->IsOnCurrentThread (&isOnMainThread); 102 eventQ = nsnull; / / early release113 eventQ = nsnull; /* early release */ 103 114 if (isOnMainThread) 104 115 { 105 / / only the main thread needs to uninitialize XPCOM116 /* only the main thread needs to uninitialize XPCOM */ 106 117 NS_ShutdownXPCOM (nsnull); 107 118 XPCOMGlueShutdown(); 108 119 } 109 120 } 121 110 122 #endif 111 123 } 112 124 125 void GetInterfaceNameByIID (const GUID &aIID, BSTR *aName) 126 { 127 Assert (aName); 128 if (!aName) 129 return; 130 131 *aName = NULL; 132 133 #if !defined (VBOX_WITH_XPCOM) 134 135 LONG rc; 136 LPOLESTR iidStr = NULL; 137 if (StringFromIID (aIID, &iidStr) == S_OK) 138 { 139 HKEY ifaceKey; 140 rc = RegOpenKeyExW (HKEY_CLASSES_ROOT, L"Interface", 141 0, KEY_QUERY_VALUE, &ifaceKey); 142 if (rc == ERROR_SUCCESS) 143 { 144 HKEY iidKey; 145 rc = RegOpenKeyExW (ifaceKey, iidStr, 0, KEY_QUERY_VALUE, &iidKey); 146 if (rc == ERROR_SUCCESS) 147 { 148 /* determine the size and type */ 149 DWORD sz, type; 150 rc = RegQueryValueExW (iidKey, NULL, NULL, &type, NULL, &sz); 151 if (rc == ERROR_SUCCESS && type == REG_SZ) 152 { 153 /* query the value to BSTR */ 154 *aName = SysAllocStringLen (NULL, (sz + 1) / 155 sizeof (TCHAR) + 1); 156 rc = RegQueryValueExW (iidKey, NULL, NULL, NULL, 157 (LPBYTE) *aName, &sz); 158 if (rc != ERROR_SUCCESS) 159 &n

