VirtualBox

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

Last change on this file was 98297, checked in by vboxsync, 16 months ago

Main: rc -> hrc/vrc for all but testcases. Enabled scm rc checks accordingly. bugref:10223

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

© 2023 Oracle
ContactPrivacy policyTerms of Use