VirtualBox

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

Last change on this file since 45927 was 45805, checked in by vboxsync, 12 years ago

Main: Removed IGuestErrorInfo, added new attribute resultDetail to IVirtualBoxErrorInfo for (optionally) providing more details on the error happened.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.7 KB
Line 
1/* $Id: ErrorInfo.cpp 45805 2013-04-29 12:30:50Z vboxsync $ */
2
3/** @file
4 *
5 * ErrorInfo class definition
6 */
7
8/*
9 * Copyright (C) 2006-2013 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 mResultDetail = x.mResultDetail;
53 mInterfaceID = x.mInterfaceID;
54 mComponent = x.mComponent;
55 mText = x.mText;
56
57 if (x.m_pNext != NULL)
58 m_pNext = new ErrorInfo(*x.m_pNext);
59 else
60 m_pNext = NULL;
61
62 mInterfaceName = x.mInterfaceName;
63 mCalleeIID = x.mCalleeIID;
64 mCalleeName = x.mCalleeName;
65
66 mErrorInfo = x.mErrorInfo;
67}
68
69void ErrorInfo::cleanup()
70{
71 mIsBasicAvailable = false;
72 mIsFullAvailable = false;
73
74 if (m_pNext)
75 {
76 delete m_pNext;
77 m_pNext = NULL;
78 }
79
80 mResultCode = S_OK;
81 mResultDetail = 0;
82 mInterfaceID.clear();
83 mComponent.setNull();
84 mText.setNull();
85 mInterfaceName.setNull();
86 mCalleeIID.clear();
87 mCalleeName.setNull();
88 mErrorInfo.setNull();
89}
90
91void ErrorInfo::init(bool aKeepObj /* = false */)
92{
93 HRESULT rc = E_FAIL;
94
95#if !defined(VBOX_WITH_XPCOM)
96
97 ComPtr<IErrorInfo> err;
98 rc = ::GetErrorInfo(0, err.asOutParam());
99 if (rc == S_OK && err)
100 {
101 if (aKeepObj)
102 mErrorInfo = err;
103
104 ComPtr<IVirtualBoxErrorInfo> info;
105 rc = err.queryInterfaceTo(info.asOutParam());
106 if (SUCCEEDED(rc) && info)
107 init(info);
108
109 if (!mIsFullAvailable)
110 {
111 bool gotSomething = false;
112
113 rc = err->GetGUID(mInterfaceID.asOutParam());
114 gotSomething |= SUCCEEDED(rc);
115 if (SUCCEEDED(rc))
116 GetInterfaceNameByIID(mInterfaceID.ref(), mInterfaceName.asOutParam());
117
118 rc = err->GetSource(mComponent.asOutParam());
119 gotSomething |= SUCCEEDED(rc);
120
121 rc = err->GetDescription(mText.asOutParam());
122 gotSomething |= SUCCEEDED(rc);
123
124 if (gotSomething)
125 mIsBasicAvailable = true;
126
127 AssertMsg(gotSomething, ("Nothing to fetch!\n"));
128 }
129 }
130
131#else // defined(VBOX_WITH_XPCOM)
132
133 nsCOMPtr<nsIExceptionService> es;
134 es = do_GetService(NS_EXCEPTIONSERVICE_CONTRACTID, &rc);
135 if (NS_SUCCEEDED(rc))
136 {
137 nsCOMPtr<nsIExceptionManager> em;
138 rc = es->GetCurrentExceptionManager(getter_AddRefs(em));
139 if (NS_SUCCEEDED(rc))
140 {
141 ComPtr<nsIException> ex;
142 rc = em->GetCurrentException(ex.asOutParam());
143 if (NS_SUCCEEDED(rc) && ex)
144 {
145 if (aKeepObj)
146 mErrorInfo = ex;
147
148 ComPtr<IVirtualBoxErrorInfo> info;
149 rc = ex.queryInterfaceTo(info.asOutParam());
150 if (NS_SUCCEEDED(rc) && info)
151 init(info);
152
153 if (!mIsFullAvailable)
154 {
155 bool gotSomething = false;
156
157 rc = ex->GetResult(&mResultCode);
158 gotSomething |= NS_SUCCEEDED(rc);
159
160 char *pszMsg;
161 rc = ex->GetMessage(&pszMsg);
162 gotSomething |= NS_SUCCEEDED(rc);
163 if (NS_SUCCEEDED(rc))
164 {
165 mText = Bstr(pszMsg);
166 nsMemory::Free(pszMsg);
167 }
168
169 if (gotSomething)
170 mIsBasicAvailable = true;
171
172 AssertMsg(gotSomething, ("Nothing to fetch!\n"));
173 }
174
175 // set the exception to NULL (to emulate Win32 behavior)
176 em->SetCurrentException(NULL);
177
178 rc = NS_OK;
179 }
180 }
181 }
182 /* Ignore failure when called after nsComponentManagerImpl::Shutdown(). */
183 else if (rc == NS_ERROR_UNEXPECTED)
184 rc = NS_OK;
185
186 AssertComRC(rc);
187
188#endif // defined(VBOX_WITH_XPCOM)
189}
190
191void ErrorInfo::init(IUnknown *aI,
192 const GUID &aIID,
193 bool aKeepObj /* = false */)
194{
195 AssertReturnVoid(aI);
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, lrd;
230
231 rc = info->COMGETTER(ResultCode)(&lrc); mResultCode = lrc;
232 gotSomething |= SUCCEEDED(rc);
233 gotAll &= SUCCEEDED(rc);
234
235 rc = info->COMGETTER(ResultDetail)(&lrd); mResultDetail = lrd;
236 gotSomething |= SUCCEEDED(rc);
237 gotAll &= SUCCEEDED(rc);
238
239 Bstr iid;
240 rc = info->COMGETTER(InterfaceID)(iid.asOutParam());
241 gotSomething |= SUCCEEDED(rc);
242 gotAll &= SUCCEEDED(rc);
243 if (SUCCEEDED(rc))
244 {
245 mInterfaceID = iid;
246 GetInterfaceNameByIID(mInterfaceID.ref(), mInterfaceName.asOutParam());
247 }
248
249 rc = info->COMGETTER(Component)(mComponent.asOutParam());
250 gotSomething |= SUCCEEDED(rc);
251 gotAll &= SUCCEEDED(rc);
252
253 rc = info->COMGETTER(Text)(mText.asOutParam());
254 gotSomething |= SUCCEEDED(rc);
255 gotAll &= SUCCEEDED(rc);
256
257 m_pNext = NULL;
258
259 ComPtr<IVirtualBoxErrorInfo> next;
260 rc = info->COMGETTER(Next)(next.asOutParam());
261 if (SUCCEEDED(rc) && !next.isNull())
262 {
263 m_pNext = new ErrorInfo(next);
264 Assert(m_pNext != NULL);
265 if (!m_pNext)
266 rc = E_OUTOFMEMORY;
267 }
268
269 gotSomething |= SUCCEEDED(rc);
270 gotAll &= SUCCEEDED(rc);
271
272 mIsBasicAvailable = gotSomething;
273 mIsFullAvailable = gotAll;
274
275 mErrorInfo = info;
276
277 AssertMsg(gotSomething, ("Nothing to fetch!\n"));
278}
279
280////////////////////////////////////////////////////////////////////////////////
281//
282// ProgressErrorInfo class
283//
284////////////////////////////////////////////////////////////////////////////////
285
286ProgressErrorInfo::ProgressErrorInfo(IProgress *progress) :
287 ErrorInfo(false /* aDummy */)
288{
289 Assert(progress);
290 if (!progress)
291 return;
292
293 ComPtr<IVirtualBoxErrorInfo> info;
294 HRESULT rc = progress->COMGETTER(ErrorInfo)(info.asOutParam());
295 if (SUCCEEDED(rc) && info)
296 init(info);
297}
298
299////////////////////////////////////////////////////////////////////////////////
300//
301// ErrorInfoKeeper class
302//
303////////////////////////////////////////////////////////////////////////////////
304
305HRESULT ErrorInfoKeeper::restore()
306{
307 if (mForgot)
308 return S_OK;
309
310 HRESULT rc = S_OK;
311
312#if !defined(VBOX_WITH_XPCOM)
313
314 ComPtr<IErrorInfo> err;
315 if (!mErrorInfo.isNull())
316 {
317 rc = mErrorInfo.queryInterfaceTo(err.asOutParam());
318 AssertComRC(rc);
319 }
320 rc = ::SetErrorInfo(0, err);
321
322#else // defined(VBOX_WITH_XPCOM)
323
324 nsCOMPtr <nsIExceptionService> es;
325 es = do_GetService(NS_EXCEPTIONSERVICE_CONTRACTID, &rc);
326 if (NS_SUCCEEDED(rc))
327 {
328 nsCOMPtr <nsIExceptionManager> em;
329 rc = es->GetCurrentExceptionManager(getter_AddRefs(em));
330 if (NS_SUCCEEDED(rc))
331 {
332 ComPtr<nsIException> ex;
333 if (!mErrorInfo.isNull())
334 {
335 rc = mErrorInfo.queryInterfaceTo(ex.asOutParam());
336 AssertComRC(rc);
337 }
338 rc = em->SetCurrentException(ex);
339 }
340 }
341
342#endif // defined(VBOX_WITH_XPCOM)
343
344 if (SUCCEEDED(rc))
345 {
346 mErrorInfo.setNull();
347 mForgot = true;
348 }
349
350 return rc;
351}
352
353} /* namespace com */
354
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