VirtualBox

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

Last change on this file since 5999 was 5999, checked in by vboxsync, 17 years ago

The Giant CDDL Dual-License Header Change.

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