VirtualBox

Changeset 2672 in vbox


Ignore:
Timestamp:
May 16, 2007 3:31:49 PM (17 years ago)
Author:
vboxsync
Message:

Main: Ported latest dmik/exp branch changes (r21219:21226) into the trunk.

Location:
trunk
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/com/ErrorInfo.h

    r1 r2672  
    2828#include "VBox/com/Guid.h"
    2929#include "VBox/com/assert.h"
     30
     31#include <iprt/memory> // for auto_copy_ptr
    3032
    3133struct IProgress;
     
    102104     *  pointer available.
    103105     */
    104     explicit ErrorInfo() :
    105         mIsBasicAvailable (false), mIsFullAvailable (false), mResultCode (S_OK)
    106     { init(); }
     106    explicit ErrorInfo()
     107        : mIsBasicAvailable (false), mIsFullAvailable (false)
     108        , mResultCode (S_OK)
     109        { init(); }
    107110
    108111    /**
     
    118121     *              error
    119122     */
    120     template <class I> ErrorInfo (I *aPtr) :
    121         mIsBasicAvailable (false), mIsFullAvailable (false), mResultCode (S_OK)
    122     { init (aPtr, COM_IIDOF(I)); }
     123    template <class I> ErrorInfo (I *aPtr)
     124        : mIsBasicAvailable (false), mIsFullAvailable (false)
     125        , mResultCode (S_OK)
     126        { init (aPtr, COM_IIDOF(I)); }
    123127
    124128    /**
     
    129133     *              an error
    130134     */
    131     template <class I> ErrorInfo (const ComPtr <I> &aPtr) :
    132         mIsBasicAvailable (false), mIsFullAvailable (false), mResultCode (S_OK)
    133     { init (static_cast <I*> (aPtr), COM_IIDOF(I)); }
     135    template <class I> ErrorInfo (const ComPtr <I> &aPtr)
     136        : mIsBasicAvailable (false), mIsFullAvailable (false)
     137        , mResultCode (S_OK)
     138        { init (static_cast <I*> (aPtr), COM_IIDOF(I)); }
    134139
    135140    /** Specialization for the IVirtualBoxErrorInfo smart pointer */
    136     ErrorInfo (const ComPtr <IVirtualBoxErrorInfo> &aPtr) :
    137         mIsBasicAvailable (false), mIsFullAvailable (false), mResultCode (S_OK)
    138     { init (aPtr); }
     141    ErrorInfo (const ComPtr <IVirtualBoxErrorInfo> &aPtr)
     142        : mIsBasicAvailable (false), mIsFullAvailable (false)
     143        , mResultCode (S_OK)
     144        { init (aPtr); }
    139145
    140146    /**
     
    146152     *                  holds error info to be fetched by this instance
    147153     */
    148     ErrorInfo (IVirtualBoxErrorInfo *aInfo) :
    149         mIsBasicAvailable (false), mIsFullAvailable (false), mResultCode (S_OK)
    150     { init (aInfo); }
    151 
    152     ~ErrorInfo();
     154    ErrorInfo (IVirtualBoxErrorInfo *aInfo)
     155        : mIsBasicAvailable (false), mIsFullAvailable (false)
     156        , mResultCode (S_OK)
     157        { init (aInfo); }
     158
     159    virtual ~ErrorInfo();
    153160
    154161    /**
     
    201208
    202209    /**
     210     *  Returns the next error information object or @c NULL if there is none.
     211     */
     212    const ErrorInfo *getNext() const { return mNext.get(); }
     213
     214    /**
    203215     *  Returns the name of the interface that defined the error
    204216     */
     
    233245protected:
    234246
    235     ErrorInfo (bool dummy) :
    236         mIsBasicAvailable (false), mIsFullAvailable (false), mResultCode (S_OK)
    237     {}
    238 
    239     void init();
    240     void init (IUnknown *i, const GUID &iid);
    241     void init (IVirtualBoxErrorInfo *info);
    242 
    243 private:
    244 
    245     bool mIsBasicAvailable;
    246     bool mIsFullAvailable;
     247    ErrorInfo (bool aDummy)
     248        : mIsBasicAvailable (false), mIsFullAvailable (false)
     249        , mResultCode (S_OK)
     250        {}
     251
     252    void init (bool aKeepObj = false);
     253    void init (IUnknown *aUnk, const GUID &aIID, bool aKeepObj = false);
     254    void init (IVirtualBoxErrorInfo *aInfo);
     255
     256    bool mIsBasicAvailable : 1;
     257    bool mIsFullAvailable : 1;
    247258
    248259    HRESULT mResultCode;
     
    251262    Bstr mText;
    252263
     264    cppx::auto_copy_ptr <ErrorInfo> mNext;
     265
    253266    Bstr mInterfaceName;
    254267    Guid mCalleeIID;
    255268    Bstr mCalleeName;
     269
     270    ComPtr <IUnknown> mErrorInfo;
    256271};
    257272
    258273/**
    259  *  A convenience subclass of ErrorInfo, that, given an IProgress interface
     274 *  A convenience subclass of ErrorInfo that, given an IProgress interface
    260275 *  pointer, reads its errorInfo attribute and uses the returned
    261276 *  IVirtualBoxErrorInfo instance to construct itself.
     
    277292};
    278293
     294/**
     295 *  A convenience subclass of ErrorInfo that allows to preserve the current
     296 *  error info. Instances of this class fetch an error info object set on the
     297 *  current thread and keep a reference to it, which allows to restore it
     298 *  later using the #restore() method. This is useful to preserve error
     299 *  information returned by some method for the duration of making another COM
     300 *  call that may set its own error info and overwrite the existing
     301 *  one. Preserving and restoring error information makes sense when some
     302 *  method wants to return error information set by other call as its own
     303 *  error information while it still needs to make another call before return.
     304 *
     305 *  The usage pattern is:
     306 *  <code>
     307 *      rc = foo->method();
     308 *      if (FAILED (rc))
     309 *      {
     310 *           ErrorInfoKeeper eik;
     311 *           ...
     312 *           // bar may return error info as well
     313 *           bar->method();
     314 *           ...
     315 *           // restore error info from foo to return it to the caller
     316 *           eik.restore();
     317 *           return rc;
     318 *      }
     319 *  </code>
     320 */
     321class ErrorInfoKeeper : public ErrorInfo
     322{
     323public:
     324
     325    /** Constructs a new instance that will fetch the current error info. */
     326    ErrorInfoKeeper() : ErrorInfo (false), mForgot (false)
     327        { init (true /* aKeepObj */); }
     328
     329    /**
     330     *  Destroys this instance and automatically calls #restore() which will
     331     *  either restorr error info fetched by the constructor or do nothing
     332     *  if #forget() was called before destruction. */
     333    ~ErrorInfoKeeper() { if (!mForgot) restore(); }
     334
     335    /**
     336     *  Restores error info fetched by the constructor and forgets it
     337     *  afterwards.
     338     *
     339     *  @return COM result of the restore operation.
     340     */
     341    HRESULT restore();
     342
     343    /**
     344     *  Forgets error info fetched by the constructor which prevents it from
     345     *  being restored by #restore() or by the destructor.
     346     */
     347    void forget() { mForgot = 0; }
     348
     349private:
     350
     351    bool mForgot : 1;
     352};
     353
    279354}; // namespace com
    280355
  • trunk/include/VBox/com/com.h

    r1 r2672  
    3838
    3939/**
    40  *  Shutdowns the COM runtime.
     40 *  Shuts down the COM runtime.
    4141 *  Must be called on every thread before termination.
    42  *  No any COM calls may be made after this method returns.
     42 *  No COM calls may be made after this method returns.
    4343 */
    4444void Shutdown();
     45
     46/**
     47 *  Resolves a given interface ID to a string containing the interface name.
     48 *  If, for some reason, the given IID cannot be resolved to a name, a NULL
     49 *  string is returned. A non-NULL string returned by this funciton must be
     50 *  freed using SysFreeString().
     51 *
     52 *  @param aIID     ID of the interface to get a name for
     53 *  @param aName    Resolved interface name or @c NULL on error
     54 */
     55void GetInterfaceNameByIID (const GUID &aIID, BSTR *aName);
    4556
    4657}; // namespace com
  • trunk/src/VBox/Main/ConsoleImpl.cpp

    r2651 r2672  
    17851785    if (FAILED (rc) && !taskCreationFailed)
    17861786    {
    1787         /* fetch any existing error info */
    1788         ErrorInfo ei;
     1787        /* preserve existing error info */
     1788        ErrorInfoKeeper eik;
    17891789
    17901790        if (beganSavingState)
     
    18071807        else
    18081808            setMachineStateLocally (lastMachineState);
    1809 
    1810         /* restore fetched error info */
    1811         setError (ei);
    18121809    }
    18131810
     
    23402337    if (FAILED (rc) && !taskCreationFailed)
    23412338    {
    2342         /* fetch any existing error info */
    2343         ErrorInfo ei;
     2339        /* preserve existing error info */
     2340        ErrorInfoKeeper eik;
    23442341
    23452342        if (beganTakingSnapshot && takingSnapshotOnline)
     
    23632360        else
    23642361            setMachineStateLocally (lastMachineState);
    2365 
    2366         /* restore fetched error info */
    2367         setError (ei);
    23682362    }
    23692363
     
    67956789            if (FAILED (hrc) || VBOX_FAILURE (vrc))
    67966790            {
    6797                 /* preserve the current error info */
    6798                 ErrorInfo ei;
     6791                /* preserve existing error info */
     6792                ErrorInfoKeeper eik;
    67996793
    68006794                /*
     
    68046798                HRESULT hrc2 = console->powerDown();
    68056799                AssertComRC (hrc2);
    6806 
    6807                 setError (ei);
    68086800            }
    68096801        }
     
    68606852         */
    68616853
    6862         /* preserve the current error info */
    6863         ErrorInfo ei;
     6854        /* preserve existing error info */
     6855        ErrorInfoKeeper eik;
    68646856
    68656857        Assert (console->mpVM == NULL);
    68666858        vmstateChangeCallback (NULL, VMSTATE_TERMINATED, VMSTATE_CREATING,
    68676859                               console);
    6868         setError (ei);
    68696860    }
    68706861
  • trunk/src/VBox/Main/MachineImpl.cpp

    r2656 r2672  
    89518951        }
    89528952
    8953         /* fetch the current error info */
    8954         ErrorInfo mergeEi;
     8953        /* preserve existing error info */
     8954        ErrorInfoKeeper mergeEik;
    89558955        HRESULT mergeRc = rc;
    89568956
     
    90269026        while (0);
    90279027
    9028         /* restore the merge error if any */
     9028        /* restore the merge error if any (ErrorInfo will be restored
     9029         * automatically) */
    90299030        if (FAILED (mergeRc))
    9030         {
    90319031            rc = mergeRc;
    9032             setError (mergeEi);
    9033         }
    90349032    }
    90359033    while (0);
     
    90399037        if (!aTask.subTask)
    90409038        {
    9041             /* save current error info */
    9042             ErrorInfo ei;
     9039            /* preserve existing error info */
     9040            ErrorInfoKeeper eik;
    90439041
    90449042            /* restore the machine state */
     
    90559053                              true /* aInformCallbacksAnyway */);
    90569054            }
    9057 
    9058             /* restore current error info */
    9059             setError (ei);
    90609055        }
    90619056
     
    91879182            {
    91889183                /* here we can still safely rollback, so do it */
    9189                 ErrorInfo ei;
     9184                /* preserve existing error info */
     9185                ErrorInfoKeeper eik;
    91909186                /* undo all changes */
    91919187                rollback (false /* aNotify */);
    9192                 setError (ei);
    91939188                break;
    91949189            }
     
    93069301    if (FAILED (rc))
    93079302    {
    9308         ErrorInfo ei;
     9303        /* preserve existing error info */
     9304        ErrorInfoKeeper eik;
    93099305
    93109306        if (!stateRestored)
     
    93289324                saveSettings();
    93299325        }
    9330 
    9331         setError (ei);
    93329326    }
    93339327
  • trunk/src/VBox/Main/VirtualBoxBase.cpp

    r1 r2672  
    641641////////////////////////////////////////////////////////////////////////////////
    642642
     643/**
     644 *  Sets error info for the current thread. This is an internal function that
     645 *  gets eventually called by all public variants.  If @a aPreserve is
     646 *  @c true, then the current error info object set on the thread before this
     647 *  method is called will be preserved in the IVirtualBoxErrorInfo::next
     648 *  attribute of the new error info object that will be then set as the
     649 *  current error info object.
     650 */
    643651// static
    644 HRESULT VirtualBoxSupportErrorInfoImplBase::setError (
    645     HRESULT resultCode, const GUID &iid,
    646     const Bstr &component,
    647     const Bstr &text)
    648 {
    649     LogRel (("ERROR [COM]: rc=%#08x IID={%Vuuid} component={%ls} text={%ls}\n",
    650               resultCode, &iid, component.raw(), text.raw()));
     652HRESULT VirtualBoxSupportErrorInfoImplBase::setErrorInternal (
     653    HRESULT aResultCode, const GUID &aIID,
     654    const Bstr &aComponent, const Bstr &aText,
     655    bool aPreserve)
     656{
     657    LogRel (("ERROR [COM]: aRC=%#08x aIID={%Vuuid} aComponent={%ls} aText={%ls} "
     658             "aPreserve=%RTbool\n",
     659             aResultCode, &aIID, aComponent.raw(), aText.raw(), aPreserve));
    651660
    652661    /* these are mandatory, others -- not */
    653     Assert (FAILED (resultCode));
    654     Assert (!text.isEmpty());
    655     if (SUCCEEDED (resultCode) || text.isEmpty())
    656         return E_FAIL;
    657 
    658     ComObjPtr <VirtualBoxErrorInfo> info;
    659     HRESULT rc = info.createObject();
    660     if (SUCCEEDED (rc))
    661     {
    662         info->init (resultCode, iid, component, text);
     662    AssertReturn (FAILED (aResultCode), E_FAIL);
     663    AssertReturn (!aText.isEmpty(), E_FAIL);
     664
     665    HRESULT rc = S_OK;
     666
     667    do
     668    {
     669        ComObjPtr <VirtualBoxErrorInfo> info;
     670        rc = info.createObject();
     671        CheckComRCBreakRC (rc);
    663672
    664673#if defined (__WIN__)
     674
     675        ComPtr <IVirtualBoxErrorInfo> curInfo;
     676        if (aPreserve)
     677        {
     678            /* get the current error info if any */
     679            ComPtr <IErrorInfo> err;
     680            rc = ::GetErrorInfo (0, err.asOutParam());
     681            CheckComRCBreakRC (rc);
     682            rc = err.queryInterfaceTo (curInfo.asOutParam());
     683            if (FAILED (rc))
     684            {
     685                /* create a IVirtualBoxErrorInfo wrapper for the native
     686                 * IErrorInfo object */
     687                ComObjPtr <VirtualBoxErrorInfo> wrapper;
     688                rc = wrapper.createObject();
     689                if (SUCCEEDED (rc))
     690                {
     691                    rc = wrapper->init (err);
     692                    if (SUCCEEDED (rc))
     693                        curInfo = wrapper;
     694                }
     695            }
     696        }
     697        /* On failure, curInfo will stay null */
     698        Assert (SUCCEEDED (rc) || curInfo.isNull());
     699
     700        /* set the current error info and preserve the previous one if any */
     701        rc = info->init (aResultCode, aIID, aComponent, aText, curInfo);
     702        CheckComRCBreakRC (rc);
    665703
    666704        ComPtr <IErrorInfo> err;
     
    677715            nsCOMPtr <nsIExceptionManager> em;
    678716            rc = es->GetCurrentExceptionManager (getter_AddRefs (em));
    679             if (NS_SUCCEEDED (rc))
     717            CheckComRCBreakRC (rc);
     718
     719            ComPtr <IVirtualBoxErrorInfo> curInfo;
     720            if (aPreserve)
    680721            {
     722                /* get the current error info if any */
    681723                ComPtr <nsIException> ex;
    682                 rc = info.queryInterfaceTo (ex.asOutParam());
    683                 if (SUCCEEDED (rc))
    684                     rc = em->SetCurrentException (ex);
     724                rc = em->GetCurrentException (ex.asOutParam());
     725                CheckComRCBreakRC (rc);
     726                rc = ex.queryInterfaceTo (curInfo.asOutParam());
     727                if (FAILED (rc))
     728                {
     729                    /* create a IVirtualBoxErrorInfo wrapper for the native
     730                     * nsIException object */
     731                    ComObjPtr <VirtualBoxErrorInfo> wrapper;
     732                    rc = wrapper.createObject();
     733                    if (SUCCEEDED (rc))
     734                    {
     735                        rc = wrapper->init (ex);
     736                        if (SUCCEEDED (rc))
     737                            curInfo = wrapper;
     738                    }
     739                }
    685740            }
     741            /* On failure, curInfo will stay null */
     742            Assert (SUCCEEDED (rc) || curInfo.isNull());
     743
     744            /* set the current error info and preserve the previous one if any */
     745            rc = info->init (aResultCode, aIID, aComponent, aText, curInfo);
     746            CheckComRCBreakRC (rc);
     747
     748            ComPtr <nsIException> ex;
     749            rc = info.queryInterfaceTo (ex.asOutParam());
     750            if (SUCCEEDED (rc))
     751                rc = em->SetCurrentException (ex);
    686752        }
    687753        else if (rc == NS_ERROR_UNEXPECTED)
     
    705771#endif // !defined (__WIN__)
    706772    }
     773    while (0);
    707774
    708775    AssertComRC (rc);
    709776
    710     return SUCCEEDED (rc) ? resultCode : rc;
    711 }
    712 
    713 // static
    714 HRESULT VirtualBoxSupportErrorInfoImplBase::setError (
    715     HRESULT resultCode, const GUID &iid,
    716     const Bstr &component,
    717     const char *text, va_list args)
    718 {
    719     return VirtualBoxSupportErrorInfoImplBase::setError (
    720         resultCode, iid, component, Utf8StrFmt (text, args));
     777    return SUCCEEDED (rc) ? aResultCode : rc;
    721778}
    722779
  • trunk/src/VBox/Main/VirtualBoxErrorInfoImpl.cpp

    r2463 r2672  
    2626////////////////////////////////////////////////////////////////////////////////
    2727
    28 void VirtualBoxErrorInfo::init (HRESULT aResultCode, const GUID &aIID,
    29                                 const BSTR aComponent, const BSTR aText,
    30                                 IVirtualBoxErrorInfo *aNext)
     28HRESULT VirtualBoxErrorInfo::init (HRESULT aResultCode, const GUID &aIID,
     29                                   const BSTR aComponent, const BSTR aText,
     30                                   IVirtualBoxErrorInfo *aNext)
    3131{
    3232    mResultCode = aResultCode;
     
    3535    mText = aText;
    3636    mNext = aNext;
     37
     38    return S_OK;
    3739}
    3840
     
    8789#if defined (__WIN__)
    8890
     91/**
     92 *  Initializes itself by fetching error information from the given error info
     93 *  object.
     94 */
     95HRESULT VirtualBoxErrorInfo::init (IErrorInfo *aInfo)
     96{
     97    AssertReturn (aInfo, E_FAIL);
     98
     99    HRESULT rc = S_OK;
     100
     101    /* We don't return a failure if talking to IErrorInfo fails below to
     102     * protect ourselves from bad IErrorInfo implementations (the
     103     * corresponding fields will simply remain null in this case). */
     104
     105    mResultCode = S_OK;
     106    rc = aInfo->GetGUID (mIID.asOutParam());
     107    AssertComRC (rc);
     108    rc = aInfo->GetSource (mComponent.asOutParam());
     109    AssertComRC (rc);
     110    rc = aInfo->GetDescription (mText.asOutParam());
     111    AssertComRC (rc);
     112   
     113    return S_OK;
     114}
     115
    89116// IErrorInfo methods
    90117////////////////////////////////////////////////////////////////////////////////
     
    116143
    117144#else // !defined (__WIN__)
     145
     146/**
     147 *  Initializes itself by fetching error information from the given error info
     148 *  object.
     149 */
     150HRESULT VirtualBoxErrorInfo::init (nsIException *aInfo)
     151{
     152    AssertReturn (aInfo, E_FAIL);
     153
     154    HRESULT rc = S_OK;
     155
     156    /* We don't return a failure if talking to nsIException fails below to
     157     * protect ourselves from bad nsIException implementations (the
     158     * corresponding fields will simply remain null in this case). */
     159
     160    rc = aInfo->GetResult (&mResultCode);
     161    AssertComRC (rc);
     162    Utf8Str message;
     163    rc = aInfo->GetMessage (message.asOutParam());
     164    AssertComRC (rc);
     165    mText = message;
     166   
     167    return S_OK;
     168}
    118169
    119170// nsIException methods
  • trunk/src/VBox/Main/glue/ErrorInfo.cpp

    r1959 r2672  
    2020 */
    2121
    22 #if defined (__WIN__)
    23 
    24 #else // !defined (__WIN__)
     22#if !defined (VBOX_WITH_XPCOM)
     23
     24#else
    2525
    2626#include <nsIServiceManager.h>
     
    2828#include <nsCOMPtr.h>
    2929
    30 #include <nsIInterfaceInfo.h>
    31 #include <nsIInterfaceInfoManager.h>
    32 
    33 #endif // !defined (__WIN__)
    34 
     30#endif
    3531
    3632#include "VBox/com/VirtualBox.h"
    3733#include "VBox/com/ErrorInfo.h"
    3834#include "VBox/com/assert.h"
     35#include "VBox/com/com.h"
    3936
    4037#include <iprt/stream.h>
    4138#include <iprt/string.h>
     39
    4240#include <VBox/err.h>
    4341
    44 /**
    45  *  Resolves a given interface ID to a string containint interface name.
    46  *  If, for some reason, the given IID cannot be resolved to a name,
    47  *  a NULL string is returned. A non-NULL interface name must be freed
    48  *  using SysFreeString().
    49  */
    50 static void GetInterfaceNameByIID (const GUID &id, BSTR *name)
    51 {
    52     Assert (name);
    53     if (!name)
    54         return;
    55 
    56     *name = NULL;
    57 
    58 #if defined (__WIN__)
    59 
    60     LONG rc;
    61     LPOLESTR iidStr = NULL;
    62     if (StringFromIID (id, &iidStr) == S_OK)
    63     {
    64         HKEY ifaceKey;
    65         rc = RegOpenKeyExW (HKEY_CLASSES_ROOT, L"Interface", 0, KEY_QUERY_VALUE, &ifaceKey);
    66         if (rc == ERROR_SUCCESS)
    67         {
    68             HKEY iidKey;
    69             rc = RegOpenKeyExW (ifaceKey, iidStr, 0, KEY_QUERY_VALUE, &iidKey);
    70             if (rc == ERROR_SUCCESS)
    71             {
    72                 // determine the size and type
    73                 DWORD sz, type;
    74                 rc = RegQueryValueExW (iidKey, NULL, NULL, &type, NULL, &sz);
    75                 if (rc == ERROR_SUCCESS && type == REG_SZ)
    76                 {
    77                     // query the value to BSTR
    78                     *name = SysAllocStringLen (NULL, (sz + 1) / sizeof (TCHAR) + 1);
    79                     rc = RegQueryValueExW (iidKey, NULL, NULL, NULL, (LPBYTE) *name, &sz);
    80                     if (rc != ERROR_SUCCESS)
    81                     {
    82                         SysFreeString (*name);
    83                         name = NULL;
    84                     }
    85                 }
    86                 RegCloseKey (iidKey);
    87             }
    88             RegCloseKey (ifaceKey);
    89         }
    90         CoTaskMemFree (iidStr);
    91     }
    92 
    93 #else
    94 
    95     nsresult rv;
    96     nsCOMPtr <nsIInterfaceInfoManager> iim =
    97         do_GetService (NS_INTERFACEINFOMANAGER_SERVICE_CONTRACTID, &rv);
    98     if (NS_SUCCEEDED (rv))
    99     {
    100         nsCOMPtr <nsIInterfaceInfo> iinfo;
    101         rv = iim->GetInfoForIID (&id, getter_AddRefs (iinfo));
    102         if (NS_SUCCEEDED (rv))
    103         {
    104             const char *iname = NULL;
    105             iinfo->GetNameShared (&iname);
    106             char *utf8IName = NULL;
    107             if (VBOX_SUCCESS (RTStrCurrentCPToUtf8 (&utf8IName, iname)))
    108             {
    109                 PRTUCS2 ucs2IName = NULL;
    110                 if (VBOX_SUCCESS (RTStrUtf8ToUcs2 (&ucs2IName, utf8IName)))
    111                 {
    112                     *name = SysAllocString ((OLECHAR *) ucs2IName);
    113                     RTStrUcs2Free (ucs2IName);
    114                 }
    115                 RTStrFree (utf8IName);
    116             }
    117         }
    118     }
    119 
    120 #endif
    121 }
    122 
    123 
    12442namespace com
    12543{
    12644
    127 // IErrorInfo class
     45// ErrorInfo class
    12846////////////////////////////////////////////////////////////////////////////////
    12947
    130 void ErrorInfo::init ()
     48void ErrorInfo::init (bool aKeepObj /* = false */)
    13149{
    13250    HRESULT rc = E_FAIL;
    13351
    134 #if defined (__WIN__)
     52#if !defined (VBOX_WITH_XPCOM)
    13553
    13654    ComPtr <IErrorInfo> err;
     
    13856    if (rc == S_OK && err)
    13957    {
     58        if (aKeepObj)
     59            mErrorInfo = err;
     60
    14061        ComPtr <IVirtualBoxErrorInfo> info;
    14162        rc = err.queryInterfaceTo (info.asOutParam());
     
    16586    }
    16687
    167 #else // !defined (__WIN__)
     88#else // !defined (VBOX_WITH_XPCOM)
    16889
    16990    nsCOMPtr <nsIExceptionService> es;
     
    179100            if (NS_SUCCEEDED (rc) && ex)
    180101            {
     102                if (aKeepObj)
     103                    mErrorInfo = ex;
     104
    181105                ComPtr <IVirtualBoxErrorInfo> info;
    182106                rc = ex.queryInterfaceTo (info.asOutParam());
     
    213137    AssertComRC (rc);
    214138
    215 #endif // !defined (__WIN__)
    216 }
    217 
    218 void ErrorInfo::init (IUnknown *i, const GUID &iid)
    219 {
    220     Assert (i);
    221     if (!i)
     139#endif // !defined (VBOX_WITH_XPCOM)
     140}
     141
     142void ErrorInfo::init (IUnknown *aI, const GUID &aIID, bool aKeepObj /* = false */)
     143{
     144    Assert (aI);
     145    if (!aI)
    222146        return;
    223147
    224 #if defined (__WIN__)
    225 
    226     ComPtr <IUnknown> iface = i;
     148#if !defined (VBOX_WITH_XPCOM)
     149
     150    ComPtr <IUnknown> iface = aI;
    227151    ComPtr <ISupportErrorInfo> serr;
    228152    HRESULT rc = iface.queryInterfaceTo (serr.asOutParam());
    229153    if (SUCCEEDED (rc))
    230154    {
    231         rc = serr->InterfaceSupportsErrorInfo (iid);
     155        rc = serr->InterfaceSupportsErrorInfo (aIID);
    232156        if (SUCCEEDED (rc))
    233             init();
    234     }
    235 
    236 #else // !defined (__WIN__)
    237 
    238     init();
    239 
    240 #endif // !defined (__WIN__)
     157            init (aKeepObj);
     158    }
     159
     160#else
     161
     162    init (aKeepObj);
     163
     164#endif
    241165
    242166    if (mIsBasicAvailable)
    243167    {
    244         mCalleeIID = iid;
    245         GetInterfaceNameByIID (iid, mCalleeName.asOutParam());
     168        mCalleeIID = aIID;
     169        GetInterfaceNameByIID (aIID, mCalleeName.asOutParam());
    246170    }
    247171}
     
    270194
    271195    rc = info->COMGETTER(Text) (mText.asOutParam());
     196    gotSomething |= SUCCEEDED (rc);
     197    gotAll &= SUCCEEDED (rc);
     198
     199    ComPtr <IVirtualBoxErrorInfo> next;
     200    rc = info->COMGETTER(Next) (next.asOutParam());
     201    if (SUCCEEDED (rc) && !next.isNull())
     202    {
     203        mNext.reset (new ErrorInfo (next));
     204        Assert (mNext.get());
     205        if (!mNext.get())
     206            rc = E_OUTOFMEMORY;
     207    }
     208    else
     209        mNext.reset();
    272210    gotSomething |= SUCCEEDED (rc);
    273211    gotAll &= SUCCEEDED (rc);
     
    300238}
    301239
    302 // IErrorInfo class
     240/**
     241 *  Sets the given error info object for the current thread.  If @a aPreserve
     242 *  is @c true, then the current error info set on the thread before this
     243 *  method is called will be preserved in the IVirtualBoxErrorInfo::next
     244 *  attribute of the new error info object that will be then set as the
     245 *  current error info object.
     246 */
     247
     248//static
     249HRESULT setError (IVirtualBoxErrorInfo *aInfo);
     250
     251// ProgressErrorInfo class
    303252////////////////////////////////////////////////////////////////////////////////
    304253
    305254ProgressErrorInfo::ProgressErrorInfo (IProgress *progress) :
    306     ErrorInfo (true)
     255    ErrorInfo (false /* aDummy */)
    307256{
    308257    Assert (progress);
     
    316265}
    317266
     267// ErrorInfoKeeper class
     268////////////////////////////////////////////////////////////////////////////////
     269
     270HRESULT ErrorInfoKeeper::restore()
     271{
     272    if (mForgot)
     273        return S_OK;
     274
     275    HRESULT rc = S_OK;
     276
     277#if !defined (VBOX_WITH_XPCOM)
     278
     279    ComPtr <IErrorInfo> err;
     280    if (!mErrorInfo.isNull())
     281    {
     282        rc = mErrorInfo.queryInterfaceTo (err.asOutParam());
     283        AssertComRC (rc);
     284    }
     285    rc = ::SetErrorInfo (0, err);
     286
     287#else // !defined (VBOX_WITH_XPCOM)
     288
     289    nsCOMPtr <nsIExceptionService> es;
     290    es = do_GetService (NS_EXCEPTIONSERVICE_CONTRACTID, &rc);
     291    if (NS_SUCCEEDED (rc))
     292    {
     293        nsCOMPtr <nsIExceptionManager> em;
     294        rc = es->GetCurrentExceptionManager (getter_AddRefs (em));
     295        if (NS_SUCCEEDED (rc))
     296        {
     297            ComPtr <nsIException> ex;
     298            if (!mErrorInfo.isNull())
     299            {
     300                rc = mErrorInfo.queryInterfaceTo (ex.asOutParam());
     301                AssertComRC (rc);
     302            }
     303            rc = em->SetCurrentException (ex);
     304        }
     305    }
     306
     307#endif // !defined (VBOX_WITH_XPCOM)
     308
     309    if (SUCCEEDED (rc))
     310    {
     311        mErrorInfo.setNull();
     312        mForgot = true;
     313    }
     314
     315    return rc;
     316}
     317
    318318}; // namespace com
    319319
  • trunk/src/VBox/Main/glue/com.cpp

    r1 r2672  
    2020 */
    2121
    22 #if defined (__WIN__)
     22#if !defined (VBOX_WITH_XPCOM)
    2323
    2424#include <objbase.h>
    2525
    26 #else // !defined (__WIN__)
     26#else
    2727
    2828#include <stdlib.h>
     
    3636#include <nsEventQueueUtils.h>
    3737
    38 #endif // !defined (__WIN__)
     38#include <nsIInterfaceInfo.h>
     39#include <nsIInterfaceInfoManager.h>
     40
     41#endif
     42
     43#include <iprt/string.h>
     44#include <VBox/err.h>
    3945
    4046#include "VBox/com/com.h"
     
    4854    HRESULT rc = E_FAIL;
    4955
    50 #if defined (__WIN__)
     56#if !defined (VBOX_WITH_XPCOM)
     57
    5158    rc = CoInitializeEx (NULL, COINIT_MULTITHREADED |
    5259                               COINIT_DISABLE_OLE1DDE |
    5360                               COINIT_SPEED_OVER_MEMORY);
    54 #else
    55     /*
    56      * Set VBOX_XPCOM_HOME if not present
    57     */
     61
     62#else
     63
     64    /* Set VBOX_XPCOM_HOME if not present */
    5865    if (!getenv("VBOX_XPCOM_HOME"))
    5966    {
     
    8289        }
    8390    }
     91
    8492#endif
    8593
     
    9199void Shutdown()
    92100{
    93 #if defined (__WIN__)
     101#if !defined (VBOX_WITH_XPCOM)
     102
    94103    CoUninitialize();
    95 #else
     104
     105#else
     106
    96107    nsCOMPtr <nsIEventQueue> eventQ;
    97108    nsresult rc = NS_GetMainEventQ (getter_AddRefs (eventQ));
     
    100111        BOOL isOnMainThread = FALSE;
    101112        eventQ->IsOnCurrentThread (&isOnMainThread);
    102         eventQ = nsnull; // early release
     113        eventQ = nsnull; /* early release */
    103114        if (isOnMainThread)
    104115        {
    105             // only the main thread needs to uninitialize XPCOM
     116            /* only the main thread needs to uninitialize XPCOM */
    106117            NS_ShutdownXPCOM (nsnull);
    107118            XPCOMGlueShutdown();
    108119        }
    109120    }
     121
    110122#endif
    111123}
    112124
     125void GetInterfaceNameByIID (const GUID &aIID, BSTR *aName)
     126{
     127    Assert (aName);
     128    if (!aName)
     129        return;
     130
     131    *aName = NULL;
     132
     133#if !defined (VBOX_WITH_XPCOM)
     134
     135    LONG rc;
     136    LPOLESTR iidStr = NULL;
     137    if (StringFromIID (aIID, &iidStr) == S_OK)
     138    {
     139        HKEY ifaceKey;
     140        rc = RegOpenKeyExW (HKEY_CLASSES_ROOT, L"Interface",
     141                            0, KEY_QUERY_VALUE, &ifaceKey);
     142        if (rc == ERROR_SUCCESS)
     143        {
     144            HKEY iidKey;
     145            rc = RegOpenKeyExW (ifaceKey, iidStr, 0, KEY_QUERY_VALUE, &iidKey);
     146            if (rc == ERROR_SUCCESS)
     147            {
     148                /* determine the size and type */
     149                DWORD sz, type;
     150                rc = RegQueryValueExW (iidKey, NULL, NULL, &type, NULL, &sz);
     151                if (rc == ERROR_SUCCESS && type == REG_SZ)
     152                {
     153                    /* query the value to BSTR */
     154                    *aName = SysAllocStringLen (NULL, (sz + 1) /
     155                                                      sizeof (TCHAR) + 1);
     156                    rc = RegQueryValueExW (iidKey, NULL, NULL, NULL,
     157                                           (LPBYTE) *aName, &sz);
     158                    if (rc != ERROR_SUCCESS)
     159                    {
     160                        SysFreeString (*aName);
     161                        aName = NULL;
     162                    }
     163                }
     164                RegCloseKey (iidKey);
     165            }
     166            RegCloseKey (ifaceKey);
     167        }
     168        CoTaskMemFree (iidStr);
     169    }
     170
     171#else
     172
     173    nsresult rv;
     174    nsCOMPtr <nsIInterfaceInfoManager> iim =
     175        do_GetService (NS_INTERFACEINFOMANAGER_SERVICE_CONTRACTID, &rv);
     176    if (NS_SUCCEEDED (rv))
     177    {
     178        nsCOMPtr <nsIInterfaceInfo> iinfo;
     179        rv = iim->GetInfoForIID (&aIID, getter_AddRefs (iinfo));
     180        if (NS_SUCCEEDED (rv))
     181        {
     182            const char *iname = NULL;
     183            iinfo->GetNameShared (&iname);
     184            char *utf8IName = NULL;
     185            if (VBOX_SUCCESS (RTStrCurrentCPToUtf8 (&utf8IName, iname)))
     186            {
     187                PRTUCS2 ucs2IName = NULL;
     188                if (VBOX_SUCCESS (RTStrUtf8ToUcs2 (&ucs2IName, utf8IName)))
     189                {
     190                    *aName = SysAllocString ((OLECHAR *) ucs2IName);
     191                    RTStrUcs2Free (ucs2IName);
     192                }
     193                RTStrFree (utf8IName);
     194            }
     195        }
     196    }
     197
     198#endif
     199}
     200
    113201}; // namespace com
  • trunk/src/VBox/Main/idl/VirtualBox.xidl

    r2602 r2672  
    365365            Sometimes invocation of some component's method may involve
    366366            methods of other components that may also fail (independently of
    367             this method's failure), or a series of non-fatal errors may precede
    368             a fatal error that causes method failure. In cases like that, it
    369             may be desirable to preserve information about all errors happened
    370             during method invocation and deliver it to the caller. The <link
    371             to="#next"/> attribute is intended specifically for this purpose
    372             and allows to represent a chain of errors through a single
    373             IVirtualBoxErrorInfo instance set after method invocation.
     367            this method's failure), or a series of non-fatal errors may
     368            precede a fatal error that causes method failure. In cases like
     369            that, it may be desirable to preserve information about all errors
     370            happened during method invocation and deliver it to the
     371            caller. The <link to="#next"/> attribute is intended specifically
     372            for this purpose and allows to represent a chain of errors through
     373            a single IVirtualBoxErrorInfo instance set after method
     374            invocation. Note that errors are stored to a chain in the reverse
     375            order, i.e. the initial error object you query right after method
     376            invocation is the last error set by the callee, the object it
     377            points to in the @a next attribute is the previous error and so
     378            on, up to the first error (which is the last in the chain).
    374379        </desc>
    375380
  • trunk/src/VBox/Main/include/VirtualBoxBase.h

    r357 r2672  
    10321032class VirtualBoxSupportErrorInfoImplBase
    10331033{
     1034    static HRESULT setErrorInternal (HRESULT aResultCode, const GUID &aIID,
     1035                                     const Bstr &aComponent, const Bstr &aText,
     1036                                     bool aPreserve);
     1037
    10341038protected:
    10351039
    1036     static HRESULT setError (HRESULT resultCode, const GUID &iid,
    1037                              const Bstr &component,
    1038                              const Bstr &text);
    1039 
    1040     static HRESULT setError (HRESULT resultCode, const GUID &iid,
    1041                              const Bstr &component,
    1042                              const char *text, va_list args);
    1043 
    1044     inline static HRESULT setError (const com::ErrorInfo &ei)
    1045     {
    1046         if (!ei.isBasicAvailable())
    1047             return S_OK;
    1048 
    1049         Assert (FAILED (ei.getResultCode()));
    1050         Assert (!ei.getText().isEmpty());
    1051         return setError (ei.getResultCode(), ei.getInterfaceID(),
    1052                          ei.getComponent(), ei.getText());
     1040    inline static HRESULT setError (HRESULT aResultCode, const GUID &aIID,
     1041                                    const Bstr &aComponent,
     1042                                    const Bstr &aText)
     1043    {
     1044        return setErrorInternal (aResultCode, aIID, aComponent, aText,
     1045                                 false /* aPreserve */);
     1046    }
     1047
     1048    inline static HRESULT addError (HRESULT aResultCode, const GUID &aIID,
     1049                                    const Bstr &aComponent,
     1050                                    const Bstr &aText)
     1051    {
     1052        return setErrorInternal (aResultCode, aIID, aComponent, aText,
     1053                                 true /* aPreserve */);
     1054    }
     1055
     1056    static HRESULT setError (HRESULT aResultCode, const GUID &aIID,
     1057                             const Bstr &aComponent,
     1058                             const char *aText, va_list aArgs)
     1059    {
     1060        return setErrorInternal (aResultCode, aIID, aComponent,
     1061                                 Utf8StrFmt (aText, aArgs),
     1062                                 false /* aPreserve */);
     1063    }
     1064
     1065    static HRESULT addError (HRESULT aResultCode, const GUID &aIID,
     1066                             const Bstr &aComponent,
     1067                             const char *aText, va_list aArgs)
     1068    {
     1069        return setErrorInternal (aResultCode, aIID, aComponent,
     1070                                 Utf8StrFmt (aText, aArgs),
     1071                                 true /* aPreserve */);
    10531072    }
    10541073};
     
    11501169     *  #setError (HRESULT, const char *, ...) for an example.
    11511170     *
    1152      *  @param  resultCode result (error) code, must not be S_OK
    1153      *  @param  iid         IID of the intrface that defines the error
    1154      *  @param  component   name of the component that generates the error
    1155      *  @param  text        error message (must not be null), an RTStrPrintf-like
     1171     *  @param  aResultCode result (error) code, must not be S_OK
     1172     *  @param  aIID        IID of the intrface that defines the error
     1173     *  @param  aComponent  name of the component that generates the error
     1174     *  @param  aText       error message (must not be null), an RTStrPrintf-like
    11561175     *                      format string in UTF-8 encoding
    11571176     *  @param  ...         list of arguments for the format string
     
    11621181     *      error argument.
    11631182     */
    1164     inline static HRESULT setError (HRESULT resultCode, const GUID &iid,
    1165                                     const wchar_t *component,
    1166                                     const char *text, ...)
     1183    inline static HRESULT setError (HRESULT aResultCode, const GUID &aIID,
     1184                                    const wchar_t *aComponent,
     1185                                    const char *aText, ...)
    11671186    {
    11681187        va_list args;
    1169         va_start (args, text);
    1170         HRESULT rc = VirtualBoxSupportErrorInfoImplBase::setError (
    1171             resultCode, iid, component, text, args);
     1188        va_start (args, aText);
     1189        HRESULT rc = VirtualBoxSupportErrorInfoImplBase::setError
     1190            (aResultCode, aIID, aComponent, aText, args);
     1191        va_end (args);
     1192        return rc;
     1193    }
     1194
     1195    /**
     1196     *  This method is the same as #setError() except that it preserves the
     1197     *  error info object (if any) set for the current thread before this
     1198     *  method is called by storing it in the IVirtualBoxErrorInfo::next
     1199     *  attribute of the new error info object.
     1200     */
     1201    inline static HRESULT addError (HRESULT aResultCode, const GUID &aIID,
     1202                                    const wchar_t *aComponent,
     1203                                    const char *aText, ...)
     1204    {
     1205        va_list args;
     1206        va_start (args, aText);
     1207        HRESULT rc = VirtualBoxSupportErrorInfoImplBase::addError
     1208            (aResultCode, aIID, aComponent, aText, args);
    11721209        va_end (args);
    11731210        return rc;
     
    11971234     *  </code>
    11981235     */
    1199     inline static HRESULT setError (HRESULT resultCode, const char *text, ...)
     1236    inline static HRESULT setError (HRESULT aResultCode, const char *aText, ...)
    12001237    {
    12011238        va_list args;
    1202         va_start (args, text);
    1203         HRESULT rc = VirtualBoxSupportErrorInfoImplBase::setError (
    1204             resultCode, COM_IIDOF(I), C::getComponentName(), text, args);
     1239        va_start (args, aText);
     1240        HRESULT rc = VirtualBoxSupportErrorInfoImplBase::setError
     1241            (aResultCode, COM_IIDOF(I), C::getComponentName(), aText, args);
     1242        va_end (args);
     1243        return rc;
     1244    }
     1245
     1246    /**
     1247     *  This method is the same as #setError() except that it preserves the
     1248     *  error info object (if any) set for the current thread before this
     1249     *  method is called by storing it in the IVirtualBoxErrorInfo::next
     1250     *  attribute of the new error info object.
     1251     */
     1252    inline static HRESULT addError (HRESULT aResultCode, const char *aText, ...)
     1253    {
     1254        va_list args;
     1255        va_start (args, aText);
     1256        HRESULT rc = VirtualBoxSupportErrorInfoImplBase::addError
     1257            (aResultCode, COM_IIDOF(I), C::getComponentName(), aText, args);
    12051258        va_end (args);
    12061259        return rc;
     
    12161269     *  and #setError (HRESULT, const char *, ...)  for details.
    12171270     */
    1218     inline static HRESULT setErrorV (HRESULT resultCode, const char *text, va_list args)
    1219     {
    1220         HRESULT rc = VirtualBoxSupportErrorInfoImplBase::setError (
    1221             resultCode, COM_IIDOF(I), C::getComponentName(), text, args);
     1271    inline static HRESULT setErrorV (HRESULT aResultCode, const char *aText,
     1272                                     va_list aArgs)
     1273    {
     1274        HRESULT rc = VirtualBoxSupportErrorInfoImplBase::setError
     1275            (aResultCode, COM_IIDOF(I), C::getComponentName(), aText, aArgs);
     1276        return rc;
     1277    }
     1278
     1279    /**
     1280     *  This method is the same as #setErrorV() except that it preserves the
     1281     *  error info object (if any) set for the current thread before this
     1282     *  method is called by storing it in the IVirtualBoxErrorInfo::next
     1283     *  attribute of the new error info object.
     1284     */
     1285    inline static HRESULT addErrorV (HRESULT aResultCode, const char *aText,
     1286                                     va_list aArgs)
     1287    {
     1288        HRESULT rc = VirtualBoxSupportErrorInfoImplBase::addError
     1289            (aResultCode, COM_IIDOF(I), C::getComponentName(), aText, aArgs);
    12221290        return rc;
    12231291    }
     
    12351303     *  and #setError (HRESULT, const char *, ...)  for details.
    12361304     */
    1237     inline static HRESULT setErrorBstr (HRESULT resultCode, const Bstr &text)
    1238     {
    1239         HRESULT rc = VirtualBoxSupportErrorInfoImplBase::setError (
    1240             resultCode, COM_IIDOF(I), C::getComponentName(), text);
     1305    inline static HRESULT setErrorBstr (HRESULT aResultCode, const Bstr &aText)
     1306    {
     1307        HRESULT rc = VirtualBoxSupportErrorInfoImplBase::setError
     1308            (aResultCode, COM_IIDOF(I), C::getComponentName(), aText);
     1309        return rc;
     1310    }
     1311
     1312    /**
     1313     *  This method is the same as #setErrorBstr() except that it preserves the
     1314     *  error info object (if any) set for the current thread before this
     1315     *  method is called by storing it in the IVirtualBoxErrorInfo::next
     1316     *  attribute of the new error info object.
     1317     */
     1318    inline static HRESULT addErrorBstr (HRESULT aResultCode, const Bstr &aText)
     1319    {
     1320        HRESULT rc = VirtualBoxSupportErrorInfoImplBase::addError
     1321            (aResultCode, COM_IIDOF(I), C::getComponentName(), aText);
    12411322        return rc;
    12421323    }
     
    12511332     *  for details.
    12521333     */
    1253     inline static HRESULT setError (HRESULT resultCode, const GUID &iid,
    1254                                     const char *text, ...)
     1334    inline static HRESULT setError (HRESULT aResultCode, const GUID &aIID,
     1335                                    const char *aText, ...)
    12551336    {
    12561337        va_list args;
    1257         va_start (args, text);
    1258         HRESULT rc = VirtualBoxSupportErrorInfoImplBase::setError (
    1259             resultCode, iid, C::getComponentName(), text, args);
     1338        va_start (args, aText);
     1339        HRESULT rc = VirtualBoxSupportErrorInfoImplBase::setError
     1340            (aResultCode, aIID, C::getComponentName(), aText, args);
    12601341        va_end (args);
    12611342        return rc;
     
    12631344
    12641345    /**
    1265      *  Sets the error information for the current thread using the error
    1266      *  information previously fetched using an ErrorInfo instance.
    1267      *  This is useful, for instance, if you want to keep the error information
    1268      *  returned by some interface's method, but need to call another method
    1269      *  of some interface prior to returning from your method (calling
    1270      *  another method will normally reset the current error information).
    1271      */
    1272     inline static HRESULT setError (const com::ErrorInfo &ei)
    1273     {
    1274         return VirtualBoxSupportErrorInfoImplBase::setError (ei);
     1346     *  This method is the same as #setError() except that it preserves the
     1347     *  error info object (if any) set for the current thread before this
     1348     *  method is called by storing it in the IVirtualBoxErrorInfo::next
     1349     *  attribute of the new error info object.
     1350     */
     1351    inline static HRESULT addError (HRESULT aResultCode, const GUID &aIID,
     1352                                    const char *aText, ...)
     1353    {
     1354        va_list args;
     1355        va_start (args, aText);
     1356        HRESULT rc = VirtualBoxSupportErrorInfoImplBase::addError
     1357            (aResultCode, aIID, C::getComponentName(), aText, args);
     1358        va_end (args);
     1359        return rc;
    12751360    }
    12761361
  • trunk/src/VBox/Main/include/VirtualBoxErrorInfoImpl.h

    r2463 r2672  
    4949
    5050#if defined (__WIN__)
     51
     52    HRESULT init (IErrorInfo *aInfo);
     53
    5154    STDMETHOD(GetGUID) (GUID *guid);
    5255    STDMETHOD(GetSource) (BSTR *source);
     
    5457    STDMETHOD(GetHelpFile) (BSTR *pBstrHelpFile);
    5558    STDMETHOD(GetHelpContext) (DWORD *pdwHelpContext);
     59
    5660#else // !defined (__WIN__)
     61
     62    HRESULT init (nsIException *aInfo);
     63
    5764    NS_DECL_NSIEXCEPTION
     65
    5866#endif
    5967
     
    6169
    6270    // public initializer/uninitializer for internal purposes only
    63     void init (HRESULT aResultCode, const GUID &aIID,
    64                const BSTR aComponent, const BSTR aText,
    65                IVirtualBoxErrorInfo *aNext = NULL);
     71    HRESULT init (HRESULT aResultCode, const GUID &aIID,
     72                  const BSTR aComponent, const BSTR aText,
     73                  IVirtualBoxErrorInfo *aNext = NULL);
    6674
    6775    // IVirtualBoxErrorInfo properties
Note: See TracChangeset for help on using the changeset viewer.

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