VirtualBox

Changeset 2672

Show
Ignore:
Timestamp:
05/16/07 17:31:49 (2 years ago)
Author:
vboxsync
Message:

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

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • 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                  &n