VirtualBox

source: vbox/trunk/src/VBox/Main/glue/ErrorInfo.cpp@ 33060

Last change on this file since 33060 was 32780, checked in by vboxsync, 14 years ago

com/Guid: remove conversion operators to eliminate any compiler surprises. Caught one totally unexpected issue which was indirectly caused by the similar Bstr cleanup, as there still is a Bstr->Guid conversion and thus the Guid magic was triggered

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.5 KB
Line 
1/* $Id: ErrorInfo.cpp 32780 2010-09-27 19:00:22Z vboxsync $ */
2
3/** @file
4 *
5 * ErrorInfo class definition
6 */
7
8/*
9 * Copyright (C) 2006-2010 Oracle Corporation
10 *
11 * This file is part of VirtualBox Open Source Edition (OSE), as
12 * available from http://www.virtualbox.org. This file is free software;
13 * you can redistribute it and/or modify it under the terms of the GNU
14 * General Public License (GPL) as published by the Free Software
15 * Foundation, in version 2 as it comes in the "COPYING" file of the
16 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
17 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
18 */
19
20#if defined(VBOX_WITH_XPCOM)
21# include <nsIServiceManager.h>
22# include <nsIExceptionService.h>
23# include <nsCOMPtr.h>
24#endif
25
26#include "VBox/com/VirtualBox.h"
27#include "VBox/com/ErrorInfo.h"
28#include "VBox/com/assert.h"
29#include "VBox/com/com.h"
30#include "VBox/com/MultiResult.h"
31
32#include <iprt/stream.h>
33#include <iprt/string.h>
34
35#include <VBox/err.h>
36
37namespace com
38{
39
40////////////////////////////////////////////////////////////////////////////////
41//
42// ErrorInfo class
43//
44////////////////////////////////////////////////////////////////////////////////
45
46void ErrorInfo::copyFrom(const ErrorInfo &x)
47{
48 mIsBasicAvailable = x.mIsBasicAvailable;
49 mIsFullAvailable = x.mIsFullAvailable;
50
51 mResultCode = x.mResultCode;
52 mInterfaceID = x.mInterfaceID;
53 mComponent = x.mComponent;
54 mText = x.mText;
55
56 if (x.m_pNext != NULL)
57 m_pNext = new ErrorInfo(*x.m_pNext);
58 else
59 m_pNext = NULL;
60
61 mInterfaceName = x.mInterfaceName;
62 mCalleeIID = x.mCalleeIID;
63 mCalleeName = x.mCalleeName;
64
65 mErrorInfo = x.mErrorInfo;
66}
67
68void ErrorInfo::cleanup()
69{
70 mIsBasicAvailable = false;
71 mIsFullAvailable = false;
72
73 if (m_pNext)
74 {
75 delete m_pNext;
76 m_pNext = NULL;
77 }
78
79 mResultCode = S_OK;
80 mInterfaceID.clear();
81 mComponent.setNull();
82 mText.setNull();
83 mInterfaceName.setNull();
84 mCalleeIID.clear();
85 mCalleeName.setNull();
86 mErrorInfo.setNull();
87}
88
89void ErrorInfo::init(bool aKeepObj /* = false */)
90{
91 HRESULT rc = E_FAIL;
92
93#if !defined(VBOX_WITH_XPCOM)
94
95 ComPtr<IErrorInfo> err;
96 rc = ::GetErrorInfo(0, err.asOutParam());
97 if (rc == S_OK && err)
98 {
99 if (aKeepObj)
100 mErrorInfo = err;
101
102 ComPtr<IVirtualBoxErrorInfo> info;
103 rc = err.queryInterfaceTo(info.asOutParam());
104 if (SUCCEEDED(rc) && info)
105 init(info);
106
107 if (!mIsFullAvailable)
108 {
109 bool gotSomething = false;
110
111 rc = err->GetGUID(mInterfaceID.asOutParam());
112 gotSomething |= SUCCEEDED(rc);
113 if (SUCCEEDED(rc))
114 GetInterfaceNameByIID(mInterfaceID.ref(), mInterfaceName.asOutParam());
115
116 rc = err->GetSource(mComponent.asOutParam());
117 gotSomething |= SUCCEEDED(rc);
118
119 rc = err->GetDescription(mText.asOutParam());
120 gotSomething |= SUCCEEDED(rc);
121
122 if (gotSomething)
123 mIsBasicAvailable = true;
124
125 AssertMsg(gotSomething, ("Nothing to fetch!\n"));
126 }
127 }
128
129#else // defined(VBOX_WITH_XPCOM)
130
131 nsCOMPtr<nsIExceptionService> es;
132 es = do_GetService(NS_EXCEPTIONSERVICE_CONTRACTID, &rc);
133 if (NS_SUCCEEDED(rc))
134 {
135 nsCOMPtr<nsIExceptionManager> em;
136 rc = es->GetCurrentExceptionManager(getter_AddRefs(em));
137 if (NS_SUCCEEDED(rc))
138 {
139 ComPtr<nsIException> ex;
140 rc = em->GetCurrentException(ex.asOutParam());
141 if (NS_SUCCEEDED(rc) && ex)
142 {
143 if (aKeepObj)
144 mErrorInfo = ex;
145
146 ComPtr<IVirtualBoxErrorInfo> info;
147 rc = ex.queryInterfaceTo(info.asOutParam());
148 if (NS_SUCCEEDED(rc) && info)
149 init(info);
150
151 if (!mIsFullAvailable)
152 {
153 bool gotSomething = false;
154
155 rc = ex->GetResult(&mResultCode);
156 gotSomething |= NS_SUCCEEDED(rc);
157
158 char *pszMsg;
159 rc = ex->GetMessage(&pszMsg);
160 gotSomething |= NS_SUCCEEDED(rc);
161 if (NS_SUCCEEDED(rc))
162 {
163 mText = Bstr(pszMsg);
164 nsMemory::Free(pszMsg);
165 }
166
167 if (gotSomething)
168 mIsBasicAvailable = true;
169
170 AssertMsg(gotSomething, ("Nothing to fetch!\n"));
171 }
172
173 // set the exception to NULL (to emulate Win32 behavior)
174 em->SetCurrentException(NULL);
175
176 rc = NS_OK;
177 }
178 }
179 }
180 /* Ignore failure when called after nsComponentManagerImpl::Shutdown(). */
181 else if (rc == NS_ERROR_UNEXPECTED)
182 rc = NS_OK;
183
184 AssertComRC(rc);
185
186#endif // defined(VBOX_WITH_XPCOM)
187}
188
189void ErrorInfo::init(IUnknown *aI,
190 const GUID &aIID,
191 bool aKeepObj /* = false */)
192{
193 Assert(aI);
194 if (!aI)
195 return;
196
197#if !defined(VBOX_WITH_XPCOM)
198
199 ComPtr<IUnknown> iface = aI;
200 ComPtr<ISupportErrorInfo> serr;
201 HRESULT rc = iface.queryInterfaceTo(serr.asOutParam());
202 if (SUCCEEDED(rc))
203 {
204 rc = serr->InterfaceSupportsErrorInfo(aIID);
205 if (SUCCEEDED(rc))
206 init(aKeepObj);
207 }
208
209#else
210
211 init(aKeepObj);
212
213#endif
214
215 if (mIsBasicAvailable)
216 {
217 mCalleeIID = aIID;
218 GetInterfaceNameByIID(aIID, mCalleeName.asOutParam());
219 }
220}
221
222void ErrorInfo::init(IVirtualBoxErrorInfo *info)
223{
224 AssertReturnVoid(info);
225
226 HRESULT rc = E_FAIL;
227 bool gotSomething = false;
228 bool gotAll = true;
229 LONG lrc;
230
231 rc = info->COMGETTER(ResultCode)(&lrc); mResultCode = lrc;
232 gotSomething |= SUCCEEDED(rc);
233 gotAll &= SUCCEEDED(rc);
234
235 Bstr iid;
236 rc = info->COMGETTER(InterfaceID)(iid.asOutParam());
237 gotSomething |= SUCCEEDED(rc);
238 gotAll &= SUCCEEDED(rc);
239 if (SUCCEEDED(rc))
240 {
241 mInterfaceID = iid;
242 GetInterfaceNameByIID(mInterfaceID.ref(), mInterfaceName.asOutParam());
243 }
244
245 rc = info->COMGETTER(Component)(mComponent.asOutParam());
246 gotSomething |= SUCCEEDED(rc);
247 gotAll &= SUCCEEDED(rc);
248
249 rc = info->COMGETTER(Text)(mText.asOutParam());
250 gotSomething |= SUCCEEDED(rc);
251 gotAll &= SUCCEEDED(rc);
252
253 m_pNext = NULL;
254
255 ComPtr<IVirtualBoxErrorInfo> next;
256 rc = info->COMGETTER(Next)(next.asOutParam());
257 if (SUCCEEDED(rc) && !next.isNull())
258 {
259 m_pNext = new ErrorInfo(next, COM_IIDOF(IVirtualBoxErrorInfo));
260 Assert(m_pNext != NULL);
261 if (!m_pNext)
262 rc = E_OUTOFMEMORY;
263 }
264
265 gotSomething |= SUCCEEDED(rc);
266 gotAll &= SUCCEEDED(rc);
267
268 mIsBasicAvailable = gotSomething;
269 mIsFullAvailable = gotAll;
270
271 AssertMsg(gotSomething, ("Nothing to fetch!\n"));
272}
273
274////////////////////////////////////////////////////////////////////////////////
275//
276// ProgressErrorInfo class
277//
278////////////////////////////////////////////////////////////////////////////////
279
280ProgressErrorInfo::ProgressErrorInfo(IProgress *progress) :
281 ErrorInfo(false /* aDummy */)
282{
283 Assert(progress);
284 if (!progress)
285 return;
286
287 ComPtr<IVirtualBoxErrorInfo> info;
288 HRESULT rc = progress->COMGETTER(ErrorInfo)(info.asOutParam());
289 if (SUCCEEDED(rc) && info)
290 init(info);
291}
292
293////////////////////////////////////////////////////////////////////////////////
294//
295// ErrorInfoKeeper class
296//
297////////////////////////////////////////////////////////////////////////////////
298
299HRESULT ErrorInfoKeeper::restore()
300{
301 if (mForgot)
302 return S_OK;
303
304 HRESULT rc = S_OK;
305
306#if !defined(VBOX_WITH_XPCOM)
307
308 ComPtr<IErrorInfo> err;
309 if (!mErrorInfo.isNull())
310 {
311 rc = mErrorInfo.queryInterfaceTo(err.asOutParam());
312 AssertComRC(rc);
313 }
314 rc = ::SetErrorInfo(0, err);
315
316#else // !defined(VBOX_WITH_XPCOM)
317
318 nsCOMPtr <nsIExceptionService> es;
319 es = do_GetService(NS_EXCEPTIONSERVICE_CONTRACTID, &rc);
320 if (NS_SUCCEEDED(rc))
321 {
322 nsCOMPtr <nsIExceptionManager> em;
323 rc = es->GetCurrentExceptionManager(getter_AddRefs(em));
324 if (NS_SUCCEEDED(rc))
325 {
326 ComPtr<nsIException> ex;
327 if (!mErrorInfo.isNull())
328 {
329 rc = mErrorInfo.queryInterfaceTo(ex.asOutParam());
330 AssertComRC(rc);
331 }
332 rc = em->SetCurrentException(ex);
333 }
334 }
335
336#endif // !defined(VBOX_WITH_XPCOM)
337
338 if (SUCCEEDED(rc))
339 {
340 mErrorInfo.setNull();
341 mForgot = true;
342 }
343
344 return rc;
345}
346
347} /* namespace com */
348
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette