ErrorInfo.h revision a126a5a0d184e3245a585414758011d1d095b35f
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/** @file
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * MS COM / XPCOM Abstraction Layer:
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * ErrorInfo class declaration
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/*
c97989161fbe75bc14cea477a5443bbf474dd3advboxsync * Copyright (C) 2006-2007 Oracle Corporation
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * available from http://www.virtualbox.org. This file is free software;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * you can redistribute it and/or modify it under the terms of the GNU
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * General Public License (GPL) as published by the Free Software
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * The contents of this file may alternatively be used under the terms
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * of the Common Development and Distribution License Version 1.0
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * VirtualBox OSE distribution, in which case the provisions of the
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * CDDL are applicable instead of those of the GPL.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * You may elect to license modified versions of this file under the
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * terms and conditions of either the GPL or the CDDL or both.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#ifndef ___VBox_com_ErrorInfo_h
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#define ___VBox_com_ErrorInfo_h
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#include "VBox/com/ptr.h"
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#include "VBox/com/string.h"
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#include "VBox/com/Guid.h"
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#include "VBox/com/assert.h"
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstruct IProgress;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstruct IVirtualBoxErrorInfo;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncnamespace com
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * The ErrorInfo class provides a convenient way to retrieve error
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * information set by the most recent interface method, that was invoked on
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * the current thread and returned an unsuccessful result code.
223cf005b18af2c21352a70693ebaf0582f68ebcvboxsync *
223cf005b18af2c21352a70693ebaf0582f68ebcvboxsync * Once the instance of this class is created, the error information for
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * the current thread is cleared.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * There is no sense to use instances of this class after the last
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * invoked interface method returns a success.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * The class usage pattern is as follows:
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * <code>
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * IFoo *foo;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * ...
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * HRESULT rc = foo->SomeMethod();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * if (FAILED (rc)) {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * ErrorInfo info (foo);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * if (info.isFullAvailable()) {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * printf ("error message = %ls\n", info.getText().raw());
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * </code>
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * This class fetches error information using the IErrorInfo interface on
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Win32 (MS COM) or the nsIException interface on other platforms (XPCOM),
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * or the extended IVirtualBoxErrorInfo interface when when it is available
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * (i.e. a given IErrorInfo or nsIException instance implements it).
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Currently, IVirtualBoxErrorInfo is only available for VirtualBox components.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * ErrorInfo::isFullAvailable() and ErrorInfo::isBasicAvailable() determine
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * what level of error information is available. If #isBasicAvailable()
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * returns true, it means that only IErrorInfo or nsIException is available as
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * the source of information (depending on the platform), but not
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * IVirtualBoxErrorInfo. If #isFullAvailable() returns true, it means that all
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * three interfaces are available. If both methods return false, no error info
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * is available at all.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Here is a table of correspondence between this class methods and
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * and IErrorInfo/nsIException/IVirtualBoxErrorInfo attributes/methods:
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * ErrorInfo IErrorInfo nsIException IVirtualBoxErrorInfo
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * --------------------------------------------------------------------
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * getResultCode -- result resultCode
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * getIID GetGUID -- interfaceID
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * getComponent GetSource -- component
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * getText GetDescription message text
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * '--' means that this interface does not provide the corresponding portion
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * of information, therefore it is useless to query it if only
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * #isBasicAvailable() returns true. As it can be seen, the amount of
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * information provided at the basic level, depends on the platform
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * (MS COM or XPCOM).
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncclass ErrorInfo
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncpublic:
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Constructs a new, "interfaceless" ErrorInfo instance that takes
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * the error information possibly set on the current thread by an
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * interface method of some COM component or by the COM subsystem.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * This constructor is useful, for example, after an unsuccessful attempt
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * to instantiate (create) a component, so there is no any valid interface
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * pointer available.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync explicit ErrorInfo()
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync : mIsBasicAvailable(false),
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mIsFullAvailable(false),
8f7bc6ad2b7bbcb4b3b96248cd2478e45f2e3b88vboxsync mResultCode(S_OK),
8f7bc6ad2b7bbcb4b3b96248cd2478e45f2e3b88vboxsync m_pNext(NULL)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync init();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ErrorInfo(IUnknown *pObj, const GUID &aIID)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync : mIsBasicAvailable(false),
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mIsFullAvailable(false),
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mResultCode(S_OK),
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync m_pNext(NULL)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync init(pObj, aIID);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync virtual ~ErrorInfo();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Returns whether basic error info is actually available for the current
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * thread. If the instance was created from an interface pointer that
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * supports basic error info and successfully provided it, or if it is an
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * "interfaceless" instance and there is some error info for the current
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * thread, the returned value will be true.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * See the class description for details about the basic error info level.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * The appropriate methods of this class provide meaningful info only when
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * this method returns true (otherwise they simply return NULL-like values).
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync bool isBasicAvailable() const
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return mIsBasicAvailable;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Returns whether full error info is actually available for the current
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * thread. If the instance was created from an interface pointer that
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * supports full error info and successfully provided it, or if it is an
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * "interfaceless" instance and there is some error info for the current
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * thread, the returned value will be true.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * See the class description for details about the full error info level.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * The appropriate methods of this class provide meaningful info only when
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * this method returns true (otherwise they simply return NULL-like values).
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync bool isFullAvailable() const
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return mIsFullAvailable;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Returns the COM result code of the failed operation.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync HRESULT getResultCode() const
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return mResultCode;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Returns the IID of the interface that defined the error.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync const Guid& getInterfaceID() const
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return mInterfaceID;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Returns the name of the component that generated the error.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync const Bstr& getComponent() const
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return mComponent;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /**
aaeb2e2f6ed5b164f1dec9a16a7adeb84f64cf31vboxsync * Returns the textual description of the error.
223cf005b18af2c21352a70693ebaf0582f68ebcvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync const Bstr& getText() const
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return mText;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Returns the next error information object or @c NULL if there is none.
aaeb2e2f6ed5b164f1dec9a16a7adeb84f64cf31vboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync const ErrorInfo* getNext() const
aaeb2e2f6ed5b164f1dec9a16a7adeb84f64cf31vboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return m_pNext;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Returns the name of the interface that defined the error
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync const Bstr& getInterfaceName() const
aaeb2e2f6ed5b164f1dec9a16a7adeb84f64cf31vboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return mInterfaceName;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Returns the IID of the interface that returned the error.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * This method returns a non-null IID only if the instance was created
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * using #template <class I> ErrorInfo (I *i) or
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * template <class I> ErrorInfo (const ComPtr <I> &i) constructor.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync const Guid& getCalleeIID() const
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return mCalleeIID;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Returns the name of the interface that returned the error
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * This method returns a non-null name only if the instance was created
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * using #template <class I> ErrorInfo (I *i) or
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * template <class I> ErrorInfo (const ComPtr <I> &i) constructor.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync const Bstr& getCalleeName() const
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return mCalleeName;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Resets all collected error information. #isNull() will
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * return @c true after this method is called.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync void setNull()
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
8a132edc1577cbe2a19cd778c1b2bea6ae5e8515vboxsync mIsBasicAvailable = false;
8a132edc1577cbe2a19cd778c1b2bea6ae5e8515vboxsync mIsFullAvailable = false;
8a132edc1577cbe2a19cd778c1b2bea6ae5e8515vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mResultCode = S_OK;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mInterfaceID.clear();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mComponent.setNull();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mText.setNull();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync m_pNext = NULL;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mInterfaceName.setNull();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mCalleeIID.clear();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mCalleeName.setNull();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mErrorInfo.setNull();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
223cf005b18af2c21352a70693ebaf0582f68ebcvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncprotected:
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ErrorInfo(bool /* aDummy */)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync : mIsBasicAvailable(false),
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mIsFullAvailable(false),
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mResultCode(S_OK)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync { }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync void init(bool aKeepObj = false);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync void init(IUnknown *aUnk, const GUID &aIID, bool aKeepObj = false);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync void init(IVirtualBoxErrorInfo *aInfo);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync bool mIsBasicAvailable : 1;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync bool mIsFullAvailable : 1;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync HRESULT mResultCode;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Guid mInterfaceID;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Bstr mComponent;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Bstr mText;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ErrorInfo *m_pNext;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Bstr mInterfaceName;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Guid mCalleeIID;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Bstr mCalleeName;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ComPtr<IUnknown> mErrorInfo;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync};
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * A convenience subclass of ErrorInfo that, given an IProgress interface
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * pointer, reads its errorInfo attribute and uses the returned
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * IVirtualBoxErrorInfo instance to construct itself.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncclass ProgressErrorInfo : public ErrorInfo
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncpublic:
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Constructs a new instance by fetching error information from the
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * IProgress interface pointer. If the progress object is not NULL,
e52f819639386db020b2a635b47a415248c7fbf9vboxsync * its completed attribute is true, resultCode represents a failure,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * and the errorInfo attribute returns a valid IVirtualBoxErrorInfo pointer,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * both #isFullAvailable() and #isBasicAvailable() will return true.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
e02db9e0d46f862430895b82b10e8ecde075cf11vboxsync * @param progress the progress object representing a failed operation
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ProgressErrorInfo(IProgress *progress);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync};
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * A convenience subclass of ErrorInfo that allows to preserve the current
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * error info. Instances of this class fetch an error info object set on the
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * current thread and keep a reference to it, which allows to restore it
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * later using the #restore() method. This is useful to preserve error
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * information returned by some method for the duration of making another COM
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * call that may set its own error info and overwrite the existing
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * one. Preserving and restoring error information makes sense when some
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * method wants to return error information set by other call as its own
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * error information while it still needs to make another call before return.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
223cf005b18af2c21352a70693ebaf0582f68ebcvboxsync * Instead of calling #restore() explicitly you may let the object destructor
223cf005b18af2c21352a70693ebaf0582f68ebcvboxsync * do it for you, if you correctly limit the object's lifetime.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * The usage pattern is:
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * <code>
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * rc = foo->method();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * if (FAILED (rc))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * ErrorInfoKeeper eik;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * ...
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * // bar may return error info as well
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * bar->method();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * ...
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * // no need to call #restore() explicitly here because the eik's
223cf005b18af2c21352a70693ebaf0582f68ebcvboxsync * // destructor will restore error info fetched after the failed
223cf005b18af2c21352a70693ebaf0582f68ebcvboxsync * // call to foo before returning to the caller
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * return rc;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * </code>
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncclass ErrorInfoKeeper : public ErrorInfo
223cf005b18af2c21352a70693ebaf0582f68ebcvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncpublic:
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Constructs a new instance that will fetch the current error info if
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @a aIsNull is @c false (by default) or remain uninitialized (null)
223cf005b18af2c21352a70693ebaf0582f68ebcvboxsync * otherwise.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @param aIsNull @c true to prevent fetching error info and leave
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * the instance uninitialized.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ErrorInfoKeeper (bool aIsNull = false)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync : ErrorInfo (false), mForgot (aIsNull)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (!aIsNull)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync init (true /* aKeepObj */);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Destroys this instance and automatically calls #restore() which will
223cf005b18af2c21352a70693ebaf0582f68ebcvboxsync * either restore error info fetched by the constructor or do nothing
223cf005b18af2c21352a70693ebaf0582f68ebcvboxsync * if #forget() was called before destruction.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ~ErrorInfoKeeper() { if (!mForgot) restore(); }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Tries to (re-)fetch error info set on the current thread. On success,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * the previous error information, if any, will be overwritten with the
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * new error information. On failure, or if there is no error information
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * available, this instance will be reset to null.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync void fetch()
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
223cf005b18af2c21352a70693ebaf0582f68ebcvboxsync setNull();
223cf005b18af2c21352a70693ebaf0582f68ebcvboxsync mForgot = false;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync init(true /* aKeepObj */);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Restores error info fetched by the constructor and forgets it
223cf005b18af2c21352a70693ebaf0582f68ebcvboxsync * afterwards. Does nothing if the error info was forgotten by #forget().
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @return COM result of the restore operation.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync HRESULT restore();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
223cf005b18af2c21352a70693ebaf0582f68ebcvboxsync /**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Forgets error info fetched by the constructor to prevent it from
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * being restored by #restore() or by the destructor.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync void forget() { mForgot = true; }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /**
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Forgets error info fetched by the constructor to prevent it from
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * being restored by #restore() or by the destructor, and returns the
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * stored error info object to the caller.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ComPtr <IUnknown> takeError() { mForgot = true; return mErrorInfo; }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncprivate:
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync bool mForgot : 1;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync};
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync} /* namespace com */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync