VirtualBox

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

Last change on this file since 30055 was 30055, checked in by vboxsync, 15 years ago

VBoxSVC: Lock order fixes (+assert) for weird shutdown case where we have to clean up a SessionMachine or two. Needs reviewing.

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

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