VirtualBox

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

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

Main: Fixed VM error callback used during powerup so that it doesn't complete the progress object but simply saves the received error message; Fixed Progress::notifyComplete() to not accept the second and subsequent calls (all for #2238).

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.8 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// ProgressErrorInfo class
237////////////////////////////////////////////////////////////////////////////////
238
239ProgressErrorInfo::ProgressErrorInfo (IProgress *progress) :
240 ErrorInfo (false /* aDummy */)
241{
242 Assert (progress);
243 if (!progress)
244 return;
245
246 ComPtr <IVirtualBoxErrorInfo> info;
247 HRESULT rc = progress->COMGETTER(ErrorInfo) (info.asOutParam());
248 if (SUCCEEDED (rc) && info)
249 init (info);
250}
251
252// ErrorInfoKeeper class
253////////////////////////////////////////////////////////////////////////////////
254
255HRESULT ErrorInfoKeeper::restore()
256{
257 if (mForgot)
258 return S_OK;
259
260 HRESULT rc = S_OK;
261
262#if !defined (VBOX_WITH_XPCOM)
263
264 ComPtr <IErrorInfo> err;
265 if (!mErrorInfo.isNull())
266 {
267 rc = mErrorInfo.queryInterfaceTo (err.asOutParam());
268 AssertComRC (rc);
269 }
270 rc = ::SetErrorInfo (0, err);
271
272#else // !defined (VBOX_WITH_XPCOM)
273
274 nsCOMPtr <nsIExceptionService> es;
275 es = do_GetService (NS_EXCEPTIONSERVICE_CONTRACTID, &rc);
276 if (NS_SUCCEEDED (rc))
277 {
278 nsCOMPtr <nsIExceptionManager> em;
279 rc = es->GetCurrentExceptionManager (getter_AddRefs (em));
280 if (NS_SUCCEEDED (rc))
281 {
282 ComPtr <nsIException> ex;
283 if (!mErrorInfo.isNull())
284 {
285 rc = mErrorInfo.queryInterfaceTo (ex.asOutParam());
286 AssertComRC (rc);
287 }
288 rc = em->SetCurrentException (ex);
289 }
290 }
291
292#endif // !defined (VBOX_WITH_XPCOM)
293
294 if (SUCCEEDED (rc))
295 {
296 mErrorInfo.setNull();
297 mForgot = true;
298 }
299
300 return rc;
301}
302
303} /* namespace com */
304
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