~ubuntu-branches/ubuntu/raring/virtualbox-ose/raring

« back to all changes in this revision

Viewing changes to src/VBox/Main/include/VirtualBoxBase.h

  • Committer: Bazaar Package Importer
  • Author(s): Felix Geyer
  • Date: 2011-01-30 23:27:25 UTC
  • mfrom: (0.3.12 upstream)
  • Revision ID: james.westby@ubuntu.com-20110130232725-2ouajjd2ggdet0zd
Tags: 4.0.2-dfsg-1ubuntu1
* Merge from Debian unstable, remaining changes:
  - Add Apport hook.
    - debian/virtualbox-ose.files/source_virtualbox-ose.py
    - debian/virtualbox-ose.install
  - Drop *-source packages.
* Drop ubuntu-01-fix-build-gcc45.patch, fixed upstream.
* Drop ubuntu-02-as-needed.patch, added to the Debian package.

Show diffs side-by-side

added added

removed removed

Lines of Context:
23
23
#include <list>
24
24
#include <map>
25
25
 
26
 
#include "VBox/com/ErrorInfo.h"
27
 
#include "VBox/com/SupportErrorInfo.h"
28
26
#include "VBox/com/AutoLock.h"
 
27
#include "VBox/com/string.h"
 
28
#include "VBox/com/Guid.h"
29
29
 
30
30
#include "VBox/com/VirtualBox.h"
31
31
 
47
47
class Medium;
48
48
class Host;
49
49
typedef std::list< ComObjPtr<Medium> > MediaList;
 
50
typedef std::list<Guid> GuidList;
50
51
 
51
52
////////////////////////////////////////////////////////////////////////////////
52
53
//
156
157
#define ComAssert(expr)    \
157
158
    do { \
158
159
        if (RT_UNLIKELY(!(expr))) \
159
 
            setError(E_FAIL, "Assertion failed: [%s] at '%s' (%d) in %s.\n" \
160
 
                             "Please contact the product vendor!", \
 
160
            setError(E_FAIL, \
 
161
                     "Assertion failed: [%s] at '%s' (%d) in %s.\nPlease contact the product vendor!", \
161
162
                     #expr, __FILE__, __LINE__, __PRETTY_FUNCTION__); \
162
163
    } while (0)
163
164
#endif
164
165
 
165
166
/**
 
167
 *  Special version of the AssertFailed macro to be used within VirtualBoxBase
 
168
 *  subclasses that also inherit the VirtualBoxSupportErrorInfoImpl template.
 
169
 *
 
170
 *  In the debug build, this macro is equivalent to AssertFailed.
 
171
 *  In the release build, this macro uses |setError(E_FAIL, ...)| to set the
 
172
 *  error info from the asserted expression.
 
173
 *
 
174
 *  @see VirtualBoxSupportErrorInfoImpl::setError
 
175
 *
 
176
 */
 
177
#if defined (DEBUG)
 
178
#define ComAssertFailed()    AssertFailed()
 
179
#else
 
180
#define ComAssertFailed()    \
 
181
    do { \
 
182
        setError(E_FAIL, \
 
183
                 "Assertion failed: at '%s' (%d) in %s.\nPlease contact the product vendor!", \
 
184
                 __FILE__, __LINE__, __PRETTY_FUNCTION__); \
 
185
    } while (0)
 
186
#endif
 
187
 
 
188
/**
166
189
 *  Special version of the AssertMsg macro to be used within VirtualBoxBase
167
190
 *  subclasses that also inherit the VirtualBoxSupportErrorInfoImpl template.
168
191
 *
177
200
#define ComAssertMsg(expr, a)  \
178
201
    do { \
179
202
        if (RT_UNLIKELY(!(expr))) \
180
 
            setError(E_FAIL, "Assertion failed: [%s] at '%s' (%d) in %s.\n" \
181
 
                             "%s.\n" \
182
 
                             "Please contact the product vendor!", \
183
 
                     #expr, __FILE__, __LINE__, __PRETTY_FUNCTION__, Utf8StrFmt a .raw()); \
 
203
            setError(E_FAIL, \
 
204
                     "Assertion failed: [%s] at '%s' (%d) in %s.\n%s.\nPlease contact the product vendor!", \
 
205
                     #expr, __FILE__, __LINE__, __PRETTY_FUNCTION__, Utf8StrFmt a .c_str()); \
184
206
    } while (0)
185
207
#endif
186
208
 
237
259
/** Special version of ComAssertRC that returns ret if vrc does not succeed */
238
260
#define ComAssertRCRet(vrc, ret)            \
239
261
    do { ComAssertRC(vrc); if (!RT_SUCCESS(vrc)) return (ret); } while (0)
240
 
/** Special version of ComAssertMsgRC that returns ret if vrc does not succeed */
241
 
#define ComAssertMsgRCRet(vrc, msg, ret)    \
242
 
    do { ComAssertMsgRC(vrc, msg); if (!RT_SUCCESS(vrc)) return (ret); } while (0)
243
 
/** Special version of ComAssertFailed that returns ret */
244
 
#define ComAssertFailedRet(ret)             \
245
 
    do { ComAssertFailed(); return (ret); } while (0)
246
 
/** Special version of ComAssertMsgFailed that returns ret */
247
 
#define ComAssertMsgFailedRet(msg, ret)     \
248
 
    do { ComAssertMsgFailed(msg); return (ret); } while (0)
249
262
/** Special version of ComAssertComRC that returns ret if rc does not succeed */
250
263
#define ComAssertComRCRet(rc, ret)          \
251
264
    do { ComAssertComRC(rc); if (!SUCCEEDED(rc)) return (ret); } while (0)
252
265
/** Special version of ComAssertComRC that returns rc if rc does not succeed */
253
266
#define ComAssertComRCRetRC(rc)             \
254
267
    do { ComAssertComRC(rc); if (!SUCCEEDED(rc)) return (rc); } while (0)
 
268
/** Special version of ComAssert that returns ret */
 
269
#define ComAssertFailedRet(ret)                \
 
270
    if (1) { ComAssertFailed(); { return (ret); } } else do {} while (0)
255
271
 
256
272
 
257
273
/** Special version of ComAssert that evaluates eval and breaks if expr fails */
263
279
/** Special version of ComAssertRC that evaluates eval and breaks if vrc does not succeed */
264
280
#define ComAssertRCBreak(vrc, eval)               \
265
281
    if (1)  { ComAssertRC(vrc); if (!RT_SUCCESS(vrc)) { eval; break; } } else do {} while (0)
266
 
/** Special version of ComAssertMsgRC that evaluates eval and breaks if vrc does not succeed */
267
 
#define ComAssertMsgRCBreak(vrc, msg, eval)       \
268
 
    if (1)  { ComAssertMsgRC(vrc, msg); if (!RT_SUCCESS(vrc)) { eval; break; } } else do {} while (0)
269
282
/** Special version of ComAssertFailed that evaluates eval and breaks */
270
283
#define ComAssertFailedBreak(eval)                \
271
284
    if (1)  { ComAssertFailed(); { eval; break; } } else do {} while (0)
283
296
/** Special version of ComAssert that evaluates eval and throws it if expr fails */
284
297
#define ComAssertThrow(expr, eval)                \
285
298
    if (1) { ComAssert(expr); if (!(expr)) { throw (eval); } } else do {} while (0)
286
 
/** Special version of ComAssertMsg that evaluates eval and throws it if expr fails */
287
 
#define ComAssertMsgThrow(expr, a, eval)          \
288
 
    if (1)  { ComAssertMsg(expr, a); if (!(expr)) { throw (eval); } } else do {} while (0)
289
299
/** Special version of ComAssertRC that evaluates eval and throws it if vrc does not succeed */
290
300
#define ComAssertRCThrow(vrc, eval)               \
291
301
    if (1)  { ComAssertRC(vrc); if (!RT_SUCCESS(vrc)) { throw (eval); } } else do {} while (0)
292
 
/** Special version of ComAssertMsgRC that evaluates eval and throws it if vrc does not succeed */
293
 
#define ComAssertMsgRCThrow(vrc, msg, eval)       \
294
 
    if (1)  { ComAssertMsgRC(vrc, msg); if (!RT_SUCCESS(vrc)) { throw (eval); } } else do {} while (0)
295
 
/** Special version of ComAssertFailed that evaluates eval and throws it */
296
 
#define ComAssertFailedThrow(eval)                \
297
 
    if (1)  { ComAssertFailed(); { throw (eval); } } else do {} while (0)
298
 
/** Special version of ComAssertMsgFailed that evaluates eval and throws it */
299
 
#define ComAssertMsgFailedThrow(msg, eval)        \
300
 
    if (1)  { ComAssertMsgFailed (msg); { throw (eval); } } else do {} while (0)
301
302
/** Special version of ComAssertComRC that evaluates eval and throws it if rc does not succeed */
302
303
#define ComAssertComRCThrow(rc, eval)             \
303
304
    if (1)  { ComAssertComRC(rc); if (!SUCCEEDED(rc)) { throw (eval); } } else do {} while (0)
304
305
/** Special version of ComAssertComRC that just throws rc if rc does not succeed */
305
306
#define ComAssertComRCThrowRC(rc)                 \
306
307
    if (1)  { ComAssertComRC(rc); if (!SUCCEEDED(rc)) { throw rc; } } else do {} while (0)
 
308
/** Special version of ComAssert that throws eval */
 
309
#define ComAssertFailedThrow(eval)                \
 
310
    if (1) { ComAssertFailed(); { throw (eval); } } else do {} while (0)
307
311
 
308
312
////////////////////////////////////////////////////////////////////////////////
309
313
 
342
346
    } while (0)
343
347
 
344
348
/**
 
349
 * Converts the Guid input argument (string) to a Guid object, returns with
 
350
 * E_INVALIDARG and error message on failure.
 
351
 *
 
352
 * @param a_Arg     Argument.
 
353
 * @param a_GuidVar The Guid variable name.
 
354
 */
 
355
#define CheckComArgGuid(a_Arg, a_GuidVar) \
 
356
    do { \
 
357
        Guid tmpGuid(a_Arg); \
 
358
        (a_GuidVar) = tmpGuid; \
 
359
        if (RT_UNLIKELY((a_GuidVar).isEmpty())) \
 
360
            return setError(E_INVALIDARG, \
 
361
                tr("GUID argument %s is not valid (\"%ls\")"), #a_Arg, Bstr(a_Arg).raw()); \
 
362
    } while (0)
 
363
 
 
364
/**
345
365
 * Checks that the given expression (that must involve the argument) is true and
346
366
 * returns E_INVALIDARG + extended error info on failure.
347
367
 * @param arg   Argument.
367
387
    do { \
368
388
        if (RT_UNLIKELY(!(expr))) \
369
389
            return setError(E_INVALIDARG, tr ("Argument %s %s"), \
370
 
                            #arg, Utf8StrFmt msg .raw()); \
 
390
                            #arg, Utf8StrFmt msg .c_str()); \
371
391
    } while (0)
372
392
 
373
393
/**
392
412
    do { \
393
413
        if (RT_UNLIKELY(ComSafeArrayOutIsNull(arg))) \
394
414
            return setError(E_POINTER, \
395
 
                tr("Output argument %s points to invalid memory location (%p)"), \
396
 
                #arg, (void *) (arg)); \
 
415
                            tr("Output argument %s points to invalid memory location (%p)"), \
 
416
                            #arg, (void*)(arg)); \
397
417
    } while (0)
398
418
 
399
419
/**
428
448
    cls::cls()  { /*empty*/ } \
429
449
    cls::~cls() { /*empty*/ }
430
450
 
 
451
/**
 
452
 *  A variant of 'throw' that hits a debug breakpoint first to make
 
453
 *  finding the actual thrower possible.
 
454
 */
 
455
#ifdef DEBUG
 
456
#define DebugBreakThrow(a) \
 
457
    do { \
 
458
        RTAssertDebugBreak(); \
 
459
        throw (a); \
 
460
} while (0)
 
461
#else
 
462
#define DebugBreakThrow(a) throw (a)
 
463
#endif
 
464
 
 
465
/**
 
466
 * Parent class of VirtualBoxBase which enables translation support (which
 
467
 * Main doesn't have yet, but this provides the tr() function which will one
 
468
 * day provide translations).
 
469
 *
 
470
 * This class sits in between Lockable and VirtualBoxBase only for the one
 
471
 * reason that the USBProxyService wants translation support but is not
 
472
 * implemented as a COM object, which VirtualBoxBase implies.
 
473
 */
 
474
class ATL_NO_VTABLE VirtualBoxTranslatable
 
475
    : public Lockable
 
476
{
 
477
public:
 
478
 
 
479
    /**
 
480
     * Placeholder method with which translations can one day be implemented
 
481
     * in Main. This gets called by the tr() function.
 
482
     * @param context
 
483
     * @param pcszSourceText
 
484
     * @param comment
 
485
     * @return
 
486
     */
 
487
    static const char *translate(const char *context,
 
488
                                 const char *pcszSourceText,
 
489
                                 const char *comment = 0)
 
490
    {
 
491
        NOREF(context);
 
492
        NOREF(comment);
 
493
        return pcszSourceText;
 
494
    }
 
495
 
 
496
    /**
 
497
     * Translates the given text string by calling translate() and passing
 
498
     * the name of the C class as the first argument ("context of
 
499
     * translation"). See VirtualBoxBase::translate() for more info.
 
500
     *
 
501
     * @param aSourceText   String to translate.
 
502
     * @param aComment      Comment to the string to resolve possible
 
503
     *                      ambiguities (NULL means no comment).
 
504
     *
 
505
     * @return Translated version of the source string in UTF-8 encoding, or
 
506
     *      the source string itself if the translation is not found in the
 
507
     *      specified context.
 
508
     */
 
509
    inline static const char *tr(const char *pcszSourceText,
 
510
                                 const char *aComment = NULL)
 
511
    {
 
512
        return VirtualBoxTranslatable::translate(NULL, // getComponentName(), eventually
 
513
                                                 pcszSourceText,
 
514
                                                 aComment);
 
515
    }
 
516
};
 
517
 
431
518
////////////////////////////////////////////////////////////////////////////////
432
519
//
433
520
// VirtualBoxBase
434
521
//
435
522
////////////////////////////////////////////////////////////////////////////////
436
523
 
 
524
#define VIRTUALBOXBASE_ADD_VIRTUAL_COMPONENT_METHODS(cls, iface) \
 
525
    virtual const IID& getClassIID() const \
 
526
    { \
 
527
        return cls::getStaticClassIID(); \
 
528
    } \
 
529
    static const IID& getStaticClassIID() \
 
530
    { \
 
531
        return COM_IIDOF(iface); \
 
532
    } \
 
533
    virtual const char* getComponentName() const \
 
534
    { \
 
535
        return cls::getStaticComponentName(); \
 
536
    } \
 
537
    static const char* getStaticComponentName() \
 
538
    { \
 
539
        return #cls; \
 
540
    }
 
541
 
437
542
/**
438
 
 * This enum is used in the virtual method VirtualBoxBasePro::getClassID() to
439
 
 * allow VirtualBox classes to identify themselves. Subclasses can override
440
 
 * that method and return a value from this enum if run-time identification is
441
 
 * needed anywhere.
 
543
 * VIRTUALBOXBASE_ADD_ERRORINFO_SUPPORT:
 
544
 * This macro must be used once in the declaration of any class derived
 
545
 * from VirtualBoxBase. It implements the pure virtual getClassIID() and
 
546
 * getComponentName() methods. If this macro is not present, instances
 
547
 * of a class derived from VirtualBoxBase cannot be instantiated.
 
548
 *
 
549
 * @param X The class name, e.g. "Class".
 
550
 * @param IX The interface name which this class implements, e.g. "IClass".
442
551
 */
443
 
enum VBoxClsID
444
 
{
445
 
    clsidVirtualBox,
446
 
    clsidHost,
447
 
    clsidMachine,
448
 
    clsidSessionMachine,
449
 
    clsidSnapshotMachine,
450
 
    clsidSnapshot,
451
 
    clsidOther
452
 
};
 
552
#ifdef VBOX_WITH_XPCOM
 
553
  #define VIRTUALBOXBASE_ADD_ERRORINFO_SUPPORT(cls, iface) \
 
554
    VIRTUALBOXBASE_ADD_VIRTUAL_COMPONENT_METHODS(cls, iface)
 
555
#else // #ifdef VBOX_WITH_XPCOM
 
556
  #define VIRTUALBOXBASE_ADD_ERRORINFO_SUPPORT(cls, iface) \
 
557
    VIRTUALBOXBASE_ADD_VIRTUAL_COMPONENT_METHODS(cls, iface) \
 
558
    STDMETHOD(InterfaceSupportsErrorInfo)(REFIID riid) \
 
559
    { \
 
560
        const _ATL_INTMAP_ENTRY* pEntries = cls::_GetEntries(); \
 
561
        Assert(pEntries); \
 
562
        if (!pEntries) \
 
563
            return S_FALSE; \
 
564
        BOOL bSupports = FALSE; \
 
565
        BOOL bISupportErrorInfoFound = FALSE; \
 
566
        while (pEntries->pFunc != NULL && !bSupports) \
 
567
        { \
 
568
            if (!bISupportErrorInfoFound) \
 
569
                bISupportErrorInfoFound = InlineIsEqualGUID(*(pEntries->piid), IID_ISupportErrorInfo); \
 
570
            else \
 
571
                bSupports = InlineIsEqualGUID(*(pEntries->piid), riid); \
 
572
            pEntries++; \
 
573
        } \
 
574
        Assert(bISupportErrorInfoFound); \
 
575
        return bSupports ? S_OK : S_FALSE; \
 
576
    }
 
577
#endif // #ifdef VBOX_WITH_XPCOM
453
578
 
454
579
/**
455
580
 * Abstract base class for all component classes implementing COM
457
582
 *
458
583
 * Declares functionality that should be available in all components.
459
584
 *
460
 
 * Note that this class is always subclassed using the virtual keyword so
461
 
 * that only one instance of its VTBL and data is present in each derived class
462
 
 * even in case if VirtualBoxBaseProto appears more than once among base classes
463
 
 * of the particular component as a result of multiple inheritance.
464
 
 *
465
 
 * This makes it possible to have intermediate base classes used by several
466
 
 * components that implement some common interface functionality but still let
467
 
 * the final component classes choose what VirtualBoxBase variant it wants to
468
 
 * use.
469
 
 *
470
585
 * Among the basic functionality implemented by this class is the primary object
471
586
 * state that indicates if the object is ready to serve the calls, and if not,
472
587
 * what stage it is currently at. Here is the primary state diagram:
516
631
 *    not recommended.
517
632
 */
518
633
class ATL_NO_VTABLE VirtualBoxBase
519
 
    : public Lockable,
 
634
    : public VirtualBoxTranslatable,
520
635
      public CComObjectRootEx<CComMultiThreadModel>
 
636
#if !defined (VBOX_WITH_XPCOM)
 
637
    , public ISupportErrorInfo
 
638
#endif
521
639
{
522
640
public:
523
641
    enum State { NotReady, Ready, InInit, InUninit, InitFailed, Limited };
525
643
    VirtualBoxBase();
526
644
    virtual ~VirtualBoxBase();
527
645
 
528
 
    static const char *translate(const char *context, const char *sourceText,
529
 
                                 const char *comment = 0);
530
 
 
531
 
public:
532
 
 
533
646
    /**
534
 
     * Unintialization method.
 
647
     * Uninitialization method.
535
648
     *
536
649
     * Must be called by all final implementations (component classes) when the
537
650
     * last reference to the object is released, before calling the destructor.
538
651
     *
539
 
     * This method is also automatically called by the uninit() method of this
540
 
     * object's parent if this object is a dependent child of a class derived
541
 
     * from VirtualBoxBaseWithChildren (see
542
 
     * VirtualBoxBaseWithChildren::addDependentChild).
543
 
     *
544
652
     * @note Never call this method the AutoCaller scope or after the
545
653
     *       #addCaller() call not paired by #releaseCaller() because it is a
546
654
     *       guaranteed deadlock. See AutoUninitSpan for details.
547
655
     */
548
 
    virtual void uninit() {}
 
656
    virtual void uninit()
 
657
    { }
549
658
 
550
 
    virtual HRESULT addCaller(State *aState = NULL, bool aLimited = false);
 
659
    virtual HRESULT addCaller(State *aState = NULL,
 
660
                              bool aLimited = false);
551
661
    virtual void releaseCaller();
552
662
 
553
663
    /**
561
671
    }
562
672
 
563
673
    /**
564
 
     * Simple run-time type identification without having to enable C++ RTTI.
565
 
     * The class IDs are defined in VirtualBoxBase.h.
566
 
     * @return
567
 
     */
568
 
    virtual VBoxClsID getClassID() const
569
 
    {
570
 
        return clsidOther;
571
 
    }
572
 
 
573
 
    /**
574
 
     * Override of the default locking class to be used for validating lock
575
 
     * order with the standard member lock handle.
 
674
     * Pure virtual method for simple run-time type identification without
 
675
     * having to enable C++ RTTI.
 
676
     *
 
677
     * This *must* be implemented by every subclass deriving from VirtualBoxBase;
 
678
     * use the VIRTUALBOXBASE_ADD_ERRORINFO_SUPPORT macro to do that most easily.
 
679
     */
 
680
    virtual const IID& getClassIID() const = 0;
 
681
 
 
682
    /**
 
683
     * Pure virtual method for simple run-time type identification without
 
684
     * having to enable C++ RTTI.
 
685
     *
 
686
     * This *must* be implemented by every subclass deriving from VirtualBoxBase;
 
687
     * use the VIRTUALBOXBASE_ADD_ERRORINFO_SUPPORT macro to do that most easily.
 
688
     */
 
689
    virtual const char* getComponentName() const = 0;
 
690
 
 
691
    /**
 
692
     * Virtual method which determines the locking class to be used for validating
 
693
     * lock order with the standard member lock handle. This method is overridden
 
694
     * in a number of subclasses.
576
695
     */
577
696
    virtual VBoxLockingClass getLockingClass() const
578
697
    {
589
708
     */
590
709
    WriteLockHandle *stateLockHandle() { return &mStateLock; }
591
710
 
 
711
    static HRESULT setErrorInternal(HRESULT aResultCode,
 
712
                                    const GUID &aIID,
 
713
                                    const char *aComponent,
 
714
                                    const Utf8Str &aText,
 
715
                                    bool aWarning,
 
716
                                    bool aLogIt);
 
717
 
 
718
    HRESULT setError(HRESULT aResultCode, const char *pcsz, ...);
 
719
    HRESULT setWarning(HRESULT aResultCode, const char *pcsz, ...);
 
720
    HRESULT setErrorNoLog(HRESULT aResultCode, const char *pcsz, ...);
 
721
 
592
722
private:
593
723
 
594
724
    void setState(State aState)
622
752
    friend class AutoUninitSpan;
623
753
};
624
754
 
625
 
////////////////////////////////////////////////////////////////////////////////
626
 
//
627
 
// VirtualBoxSupportTranslation, VirtualBoxSupportErrorInfoImpl
628
 
//
629
 
////////////////////////////////////////////////////////////////////////////////
630
 
 
631
 
/**
632
 
 *  This macro adds the error info support to methods of the VirtualBoxBase
633
 
 *  class (by overriding them). Place it to the public section of the
634
 
 *  VirtualBoxBase subclass and the following methods will set the extended
635
 
 *  error info in case of failure instead of just returning the result code:
636
 
 *
637
 
 *  <ul>
638
 
 *      <li>VirtualBoxBase::addCaller()
639
 
 *  </ul>
640
 
 *
641
 
 *  @note The given VirtualBoxBase subclass must also inherit from both
642
 
 *  VirtualBoxSupportErrorInfoImpl and VirtualBoxSupportTranslation templates!
643
 
 *
644
 
 *  @param C    VirtualBoxBase subclass to add the error info support to
645
 
 */
646
 
#define VIRTUALBOXBASE_ADD_ERRORINFO_SUPPORT(C) \
647
 
    virtual HRESULT addCaller(VirtualBoxBase::State *aState = NULL, \
648
 
                              bool aLimited = false) \
649
 
    { \
650
 
        VirtualBoxBase::State protoState; \
651
 
        HRESULT rc = VirtualBoxBase::addCaller(&protoState, aLimited); \
652
 
        if (FAILED(rc)) \
653
 
        { \
654
 
            if (protoState == VirtualBoxBase::Limited) \
655
 
                rc = setError(rc, tr("The object functionality is limited")); \
656
 
            else \
657
 
                rc = setError(rc, tr("The object is not ready")); \
658
 
        } \
659
 
        if (aState) \
660
 
            *aState = protoState; \
661
 
        return rc; \
662
 
    } \
663
 
 
664
 
////////////////////////////////////////////////////////////////////////////////
665
 
 
666
 
/** Helper for VirtualBoxSupportTranslation. */
667
 
class VirtualBoxSupportTranslationBase
668
 
{
669
 
protected:
670
 
    static bool cutClassNameFrom__PRETTY_FUNCTION__(char *aPrettyFunctionName);
671
 
};
672
 
 
673
 
/**
674
 
 * The VirtualBoxSupportTranslation template implements the NLS string
675
 
 * translation support for the given class.
676
 
 *
677
 
 * Translation support is provided by the static #tr() function. This function,
678
 
 * given a string in UTF-8 encoding, looks up for a translation of the given
679
 
 * string by calling the VirtualBoxBase::translate() global function which
680
 
 * receives the name of the enclosing class ("context of translation") as the
681
 
 * additional argument and returns a translated string based on the currently
682
 
 * active language.
683
 
 *
684
 
 * @param C     Class that needs to support the string translation.
685
 
 *
686
 
 * @note Every class that wants to use the #tr() function in its own methods
687
 
 *       must inherit from this template, regardless of whether its base class
688
 
 *       (if any) inherits from it or not. Otherwise, the translation service
689
 
 *       will not work correctly. However, the declaration of the derived
690
 
 *       class must contain
691
 
 *       the <tt>COM_SUPPORTTRANSLATION_OVERRIDE (<ClassName>)</tt> macro if one
692
 
 *       of its base classes also inherits from this template (to resolve the
693
 
 *       ambiguity of the #tr() function).
694
 
 */
695
 
template<class C>
696
 
class VirtualBoxSupportTranslation : virtual protected VirtualBoxSupportTranslationBase
697
 
{
698
 
public:
699
 
 
700
 
    /**
701
 
     * Translates the given text string by calling VirtualBoxBase::translate()
702
 
     * and passing the name of the C class as the first argument ("context of
703
 
     * translation") See VirtualBoxBase::translate() for more info.
704
 
     *
705
 
     * @param aSourceText   String to translate.
706
 
     * @param aComment      Comment to the string to resolve possible
707
 
     *                      ambiguities (NULL means no comment).
708
 
     *
709
 
     * @return Translated version of the source string in UTF-8 encoding, or
710
 
     *      the source string itself if the translation is not found in the
711
 
     *      specified context.
712
 
     */
713
 
    inline static const char *tr(const char *aSourceText,
714
 
                                 const char *aComment = NULL)
715
 
    {
716
 
        return VirtualBoxBase::translate(className(), aSourceText, aComment);
717
 
    }
718
 
 
719
 
protected:
720
 
 
721
 
    static const char *className()
722
 
    {
723
 
        static char fn[sizeof(__PRETTY_FUNCTION__) + 1];
724
 
        if (!sClassName)
725
 
        {
726
 
            strcpy(fn, __PRETTY_FUNCTION__);
727
 
            cutClassNameFrom__PRETTY_FUNCTION__(fn);
728
 
            sClassName = fn;
729
 
        }
730
 
        return sClassName;
731
 
    }
732
 
 
733
 
private:
734
 
 
735
 
    static const char *sClassName;
736
 
};
737
 
 
738
 
template<class C>
739
 
const char *VirtualBoxSupportTranslation<C>::sClassName = NULL;
740
 
 
741
 
/**
742
 
 * This macro must be invoked inside the public section of the declaration of
743
 
 * the class inherited from the VirtualBoxSupportTranslation template in case
744
 
 * if one of its other base classes also inherits from that template. This is
745
 
 * necessary to resolve the ambiguity of the #tr() function.
746
 
 *
747
 
 * @param C     Class that inherits the VirtualBoxSupportTranslation template
748
 
 *              more than once (through its other base clases).
749
 
 */
750
 
#define VIRTUALBOXSUPPORTTRANSLATION_OVERRIDE(C) \
751
 
    inline static const char *tr(const char *aSourceText, \
752
 
                                 const char *aComment = NULL) \
753
 
    { \
754
 
        return VirtualBoxSupportTranslation<C>::tr(aSourceText, aComment); \
755
 
    }
756
 
 
757
755
/**
758
756
 * Dummy macro that is used to shut down Qt's lupdate tool warnings in some
759
757
 * situations. This macro needs to be present inside (better at the very
764
762
 
765
763
////////////////////////////////////////////////////////////////////////////////
766
764
 
767
 
/**
768
 
 *  Helper for the VirtualBoxSupportErrorInfoImpl template.
769
 
 */
770
 
/// @todo switch to com::SupportErrorInfo* and remove
771
 
class VirtualBoxSupportErrorInfoImplBase
772
 
{
773
 
    static HRESULT setErrorInternal(HRESULT aResultCode,
774
 
                                    const GUID &aIID,
775
 
                                    const wchar_t *aComponent,
776
 
                                    const Bstr &aText,
777
 
                                    bool aWarning,
778
 
                                    bool aLogIt);
779
 
 
780
 
protected:
781
 
 
782
 
    /**
783
 
     * The MultiResult class is a com::FWResult enhancement that also acts as a
784
 
     * switch to turn on multi-error mode for #setError() or #setWarning()
785
 
     * calls.
786
 
     *
787
 
     * When an instance of this class is created, multi-error mode is turned on
788
 
     * for the current thread and the turn-on counter is increased by one. In
789
 
     * multi-error mode, a call to #setError() or #setWarning() does not
790
 
     * overwrite the current error or warning info object possibly set on the
791
 
     * current thread by other method calls, but instead it stores this old
792
 
     * object in the IVirtualBoxErrorInfo::next attribute of the new error
793
 
     * object being set.
794
 
     *
795
 
     * This way, error/warning objects are stacked together and form a chain of
796
 
     * errors where the most recent error is the first one retrieved by the
797
 
     * calling party, the preceding error is what the
798
 
     * IVirtualBoxErrorInfo::next attribute of the first error points to, and so
799
 
     * on, up to the first error or warning occurred which is the last in the
800
 
     * chain. See IVirtualBoxErrorInfo documentation for more info.
801
 
     *
802
 
     * When the instance of the MultiResult class goes out of scope and gets
803
 
     * destroyed, it automatically decreases the turn-on counter by one. If
804
 
     * the counter drops to zero, multi-error mode for the current thread is
805
 
     * turned off and the thread switches back to single-error mode where every
806
 
     * next error or warning object overwrites the previous one.
807
 
     *
808
 
     * Note that the caller of a COM method uses a non-S_OK result code to
809
 
     * decide if the method has returned an error (negative codes) or a warning
810
 
     * (positive non-zero codes) and will query extended error info only in
811
 
     * these two cases. However, since multi-error mode implies that the method
812
 
     * doesn't return control return to the caller immediately after the first
813
 
     * error or warning but continues its execution, the functionality provided
814
 
     * by the base com::FWResult class becomes very useful because it allows to
815
 
     * preserve the error or the warning result code even if it is later assigned
816
 
     * a S_OK value multiple times. See com::FWResult for details.
817
 
     *
818
 
     * Here is the typical usage pattern:
819
 
     *  <code>
820
 
 
821
 
        HRESULT Bar::method()
822
 
        {
823
 
            // assume multi-errors are turned off here...
824
 
 
825
 
            if (something)
826
 
            {
827
 
                // Turn on multi-error mode and make sure severity is preserved
828
 
                MultiResult rc = foo->method1();
829
 
 
830
 
                // return on fatal error, but continue on warning or on success
831
 
                if (FAILED(rc)) return rc;
832
 
 
833
 
                rc = foo->method2();
834
 
                // no matter what result, stack it and continue
835
 
 
836
 
                // ...
837
 
 
838
 
                // return the last worst result code (it will be preserved even if
839
 
                // foo->method2() returns S_OK.
840
 
                return rc;
841
 
            }
842
 
 
843
 
            // multi-errors are turned off here again...
844
 
 
845
 
            return S_OK;
846
 
        }
847
 
 
848
 
     *  </code>
849
 
     *
850
 
     *
851
 
     * @note This class is intended to be instantiated on the stack, therefore
852
 
     *       You cannot create them using new(). Although it is possible to copy
853
 
     *       instances of MultiResult or return them by value, please never do
854
 
     *       that as it is breaks the class semantics (and will assert).
855
 
     */
856
 
    class MultiResult : public com::FWResult
857
 
    {
858
 
    public:
859
 
 
860
 
        /**
861
 
         * @copydoc com::FWResult::FWResult().
862
 
         */
863
 
        MultiResult(HRESULT aRC = E_FAIL) : FWResult(aRC) { init(); }
864
 
 
865
 
        MultiResult(const MultiResult &aThat) : FWResult(aThat)
866
 
        {
867
 
            /* We need this copy constructor only for GCC that wants to have
868
 
             * it in case of expressions like |MultiResult rc = E_FAIL;|. But
869
 
             * we assert since the optimizer should actually avoid the
870
 
             * temporary and call the other constructor directly instead. */
871
 
            AssertFailed();
872
 
            init();
873
 
        }
874
 
 
875
 
        ~MultiResult();
876
 
 
877
 
        MultiResult &operator=(HRESULT aRC)
878
 
        {
879
 
            com::FWResult::operator=(aRC);
880
 
            return *this;
881
 
        }
882
 
 
883
 
        MultiResult &operator=(const MultiResult &aThat)
884
 
        {
885
 
            /* We need this copy constructor only for GCC that wants to have
886
 
             * it in case of expressions like |MultiResult rc = E_FAIL;|. But
887
 
             * we assert since the optimizer should actually avoid the
888
 
             * temporary and call the other constructor directly instead. */
889
 
            AssertFailed();
890
 
            com::FWResult::operator=(aThat);
891
 
            return *this;
892
 
        }
893
 
 
894
 
    private:
895
 
 
896
 
        DECLARE_CLS_NEW_DELETE_NOOP(MultiResult)
897
 
 
898
 
        void init();
899
 
 
900
 
        static RTTLS sCounter;
901
 
 
902
 
        friend class VirtualBoxSupportErrorInfoImplBase;
903
 
    };
904
 
 
905
 
    static HRESULT setError(HRESULT aResultCode,
906
 
                            const GUID &aIID,
907
 
                            const wchar_t *aComponent,
908
 
                            const Bstr &aText,
909
 
                            bool aLogIt = true)
910
 
    {
911
 
        return setErrorInternal(aResultCode, aIID, aComponent, aText,
912
 
                                false /* aWarning */, aLogIt);
913
 
    }
914
 
 
915
 
    static HRESULT setWarning(HRESULT aResultCode,
916
 
                              const GUID &aIID,
917
 
                              const wchar_t *aComponent,
918
 
                              const Bstr &aText)
919
 
    {
920
 
        return setErrorInternal(aResultCode, aIID, aComponent, aText,
921
 
                                true /* aWarning */, true /* aLogIt */);
922
 
    }
923
 
 
924
 
    static HRESULT setError(HRESULT aResultCode,
925
 
                            const GUID &aIID,
926
 
                            const wchar_t *aComponent,
927
 
                            const char *aText, va_list aArgs, bool aLogIt = true)
928
 
    {
929
 
        return setErrorInternal(aResultCode, aIID, aComponent,
930
 
                                Utf8StrFmtVA (aText, aArgs),
931
 
                                false /* aWarning */, aLogIt);
932
 
    }
933
 
 
934
 
    static HRESULT setWarning(HRESULT aResultCode,
935
 
                              const GUID &aIID,
936
 
                              const wchar_t *aComponent,
937
 
                              const char *aText, va_list aArgs)
938
 
    {
939
 
        return setErrorInternal(aResultCode, aIID, aComponent,
940
 
                                Utf8StrFmtVA (aText, aArgs),
941
 
                                true /* aWarning */, true /* aLogIt */);
942
 
    }
943
 
};
944
 
 
945
 
/**
946
 
 *  This template implements ISupportErrorInfo for the given component class
947
 
 *  and provides the #setError() method to conveniently set the error information
948
 
 *  from within interface methods' implementations.
949
 
 *
950
 
 *  On Windows, the template argument must define a COM interface map using
951
 
 *  BEGIN_COM_MAP / END_COM_MAP macros and this map must contain a
952
 
 *  COM_INTERFACE_ENTRY(ISupportErrorInfo) definition. All interface entries
953
 
 *  that follow it will be considered to support IErrorInfo, i.e. the
954
 
 *  InterfaceSupportsErrorInfo() implementation will return S_OK for the
955
 
 *  corresponding IID.
956
 
 *
957
 
 *  On all platforms, the template argument must also define the following
958
 
 *  method: |public static const wchar_t *C::getComponentName()|. See
959
 
 *  #setError(HRESULT, const char *, ...) for a description on how it is
960
 
 *  used.
961
 
 *
962
 
 *  @param C
963
 
 *      component class that implements one or more COM interfaces
964
 
 *  @param I
965
 
 *      default interface for the component. This interface's IID is used
966
 
 *      by the shortest form of #setError, for convenience.
967
 
 */
968
 
/// @todo switch to com::SupportErrorInfo* and remove
969
 
template<class C, class I>
970
 
class ATL_NO_VTABLE VirtualBoxSupportErrorInfoImpl
971
 
    : protected VirtualBoxSupportErrorInfoImplBase
972
 
#if !defined (VBOX_WITH_XPCOM)
973
 
    , public ISupportErrorInfo
974
 
#else
975
 
#endif
976
 
{
977
 
public:
978
 
 
979
 
#if !defined (VBOX_WITH_XPCOM)
980
 
    STDMETHOD(InterfaceSupportsErrorInfo)(REFIID riid)
981
 
    {
982
 
        const _ATL_INTMAP_ENTRY* pEntries = C::_GetEntries();
983
 
        Assert(pEntries);
984
 
        if (!pEntries)
985
 
            return S_FALSE;
986
 
 
987
 
        BOOL bSupports = FALSE;
988
 
        BOOL bISupportErrorInfoFound = FALSE;
989
 
 
990
 
        while (pEntries->pFunc != NULL && !bSupports)
991
 
        {
992
 
            if (!bISupportErrorInfoFound)
993
 
            {
994
 
                // skip the com map entries until ISupportErrorInfo is found
995
 
                bISupportErrorInfoFound =
996
 
                    InlineIsEqualGUID(*(pEntries->piid), IID_ISupportErrorInfo);
997
 
            }
998
 
            else
999
 
            {
1000
 
                // look for the requested interface in the rest of the com map
1001
 
                bSupports = InlineIsEqualGUID(*(pEntries->piid), riid);
1002
 
            }
1003
 
            pEntries++;
1004
 
        }
1005
 
 
1006
 
        Assert(bISupportErrorInfoFound);
1007
 
 
1008
 
        return bSupports ? S_OK : S_FALSE;
1009
 
    }
1010
 
#endif // !defined (VBOX_WITH_XPCOM)
1011
 
 
1012
 
protected:
1013
 
 
1014
 
    /**
1015
 
     *  Sets the error information for the current thread.
1016
 
     *  This information can be retrieved by a caller of an interface method
1017
 
     *  using IErrorInfo on Windows or nsIException on Linux, or the cross-platform
1018
 
     *  IVirtualBoxErrorInfo interface that provides extended error info (only
1019
 
     *  for components from the VirtualBox COM library). Alternatively, the
1020
 
     *  platform-independent class com::ErrorInfo (defined in VBox[XP]COM.lib)
1021
 
     *  can be used to retrieve error info in a convenient way.
1022
 
     *
1023
 
     *  It is assumed that the interface method that uses this function returns
1024
 
     *  an unsuccessful result code to the caller (otherwise, there is no reason
1025
 
     *  for the caller to try to retrieve error info after method invocation).
1026
 
     *
1027
 
     *  Here is a table of correspondence between this method's arguments
1028
 
     *  and IErrorInfo/nsIException/IVirtualBoxErrorInfo attributes/methods:
1029
 
     *
1030
 
     *  argument    IErrorInfo      nsIException    IVirtualBoxErrorInfo
1031
 
     *  ----------------------------------------------------------------
1032
 
     *  resultCode  --              result          resultCode
1033
 
     *  iid         GetGUID         --              interfaceID
1034
 
     *  component   GetSource       --              component
1035
 
     *  text        GetDescription  message         text
1036
 
     *
1037
 
     *  This method is rarely needs to be used though. There are more convenient
1038
 
     *  overloaded versions, that automatically substitute some arguments
1039
 
     *  taking their values from the template parameters. See
1040
 
     *  #setError(HRESULT, const char *, ...) for an example.
1041
 
     *
1042
 
     *  @param  aResultCode result (error) code, must not be S_OK
1043
 
     *  @param  aIID        IID of the interface that defines the error
1044
 
     *  @param  aComponent  name of the component that generates the error
1045
 
     *  @param  aText       error message (must not be null), an RTStrPrintf-like
1046
 
     *                      format string in UTF-8 encoding
1047
 
     *  @param  ...         list of arguments for the format string
1048
 
     *
1049
 
     *  @return
1050
 
     *      the error argument, for convenience, If an error occurs while
1051
 
     *      creating error info itself, that error is returned instead of the
1052
 
     *      error argument.
1053
 
     */
1054
 
    static HRESULT setError(HRESULT aResultCode, const GUID &aIID,
1055
 
                            const wchar_t *aComponent,
1056
 
                            const char *aText, ...)
1057
 
    {
1058
 
        va_list args;
1059
 
        va_start(args, aText);
1060
 
        HRESULT rc = VirtualBoxSupportErrorInfoImplBase::setError(aResultCode,
1061
 
                                                                  aIID,
1062
 
                                                                  aComponent,
1063
 
                                                                  aText,
1064
 
                                                                  args,
1065
 
                                                                  true /* aLogIt */);
1066
 
        va_end(args);
1067
 
        return rc;
1068
 
    }
1069
 
 
1070
 
    /**
1071
 
     *  This method is the same as #setError() except that it makes sure @a
1072
 
     *  aResultCode doesn't have the error severity bit (31) set when passed
1073
 
     *  down to the created IVirtualBoxErrorInfo object.
1074
 
     *
1075
 
     *  The error severity bit is always cleared by this call, thereof you can
1076
 
     *  use ordinary E_XXX result code constants, for convenience. However, this
1077
 
     *  behavior may be non-standard on some COM platforms.
1078
 
     */
1079
 
    static HRESULT setWarning(HRESULT aResultCode, const GUID &aIID,
1080
 
                              const wchar_t *aComponent,
1081
 
                              const char *aText, ...)
1082
 
    {
1083
 
        va_list args;
1084
 
        va_start(args, aText);
1085
 
        HRESULT rc = VirtualBoxSupportErrorInfoImplBase::setWarning(
1086
 
            aResultCode, aIID, aComponent, aText, args);
1087
 
        va_end(args);
1088
 
        return rc;
1089
 
    }
1090
 
 
1091
 
    /**
1092
 
     *  Sets the error information for the current thread.
1093
 
     *  A convenience method that automatically sets the default interface
1094
 
     *  ID (taken from the I template argument) and the component name
1095
 
     *  (a value of C::getComponentName()).
1096
 
     *
1097
 
     *  See #setError(HRESULT, const GUID &, const wchar_t *, const char *text, ...)
1098
 
     *  for details.
1099
 
     *
1100
 
     *  This method is the most common (and convenient) way  to set error
1101
 
     *  information from within interface methods. A typical pattern of usage
1102
 
     *  is looks like this:
1103
 
     *
1104
 
     *  <code>
1105
 
     *      return setError(E_FAIL, "Terrible Error");
1106
 
     *  </code>
1107
 
     *  or
1108
 
     *  <code>
1109
 
     *      HRESULT rc = setError(E_FAIL, "Terrible Error");
1110
 
     *      ...
1111
 
     *      return rc;
1112
 
     *  </code>
1113
 
     */
1114
 
    static HRESULT setError(HRESULT aResultCode, const char *aText, ...)
1115
 
    {
1116
 
        va_list args;
1117
 
        va_start(args, aText);
1118
 
        HRESULT rc = VirtualBoxSupportErrorInfoImplBase::setError(aResultCode,
1119
 
                                                                  COM_IIDOF(I),
1120
 
                                                                  C::getComponentName(),
1121
 
                                                                  aText,
1122
 
                                                                  args,
1123
 
                                                                  true /* aLogIt */);
1124
 
        va_end(args);
1125
 
        return rc;
1126
 
    }
1127
 
 
1128
 
    /**
1129
 
     *  This method is the same as #setError() except that it makes sure @a
1130
 
     *  aResultCode doesn't have the error severity bit (31) set when passed
1131
 
     *  down to the created IVirtualBoxErrorInfo object.
1132
 
     *
1133
 
     *  The error severity bit is always cleared by this call, thereof you can
1134
 
     *  use ordinary E_XXX result code constants, for convenience. However, this
1135
 
     *  behavior may be non-standard on some COM platforms.
1136
 
     */
1137
 
    static HRESULT setWarning(HRESULT aResultCode, const char *aText, ...)
1138
 
    {
1139
 
        va_list args;
1140
 
        va_start(args, aText);
1141
 
        HRESULT rc = VirtualBoxSupportErrorInfoImplBase::setWarning(aResultCode,
1142
 
                                                                    COM_IIDOF(I),
1143
 
                                                                    C::getComponentName(),
1144
 
                                                                    aText,
1145
 
                                                                    args);
1146
 
        va_end(args);
1147
 
        return rc;
1148
 
    }
1149
 
 
1150
 
    /**
1151
 
     *  Sets the error information for the current thread, va_list variant.
1152
 
     *  A convenience method that automatically sets the default interface
1153
 
     *  ID (taken from the I template argument) and the component name
1154
 
     *  (a value of C::getComponentName()).
1155
 
     *
1156
 
     *  See #setError(HRESULT, const GUID &, const wchar_t *, const char *text, ...)
1157
 
     *  and #setError(HRESULT, const char *, ...)  for details.
1158
 
     */
1159
 
    static HRESULT setErrorV(HRESULT aResultCode, const char *aText,
1160
 
                             va_list aArgs)
1161
 
    {
1162
 
        HRESULT rc = VirtualBoxSupportErrorInfoImplBase::setError(aResultCode,
1163
 
                                                                  COM_IIDOF(I),
1164
 
                                                                  C::getComponentName(),
1165
 
                                                                  aText,
1166
 
                                                                  aArgs,
1167
 
                                                                  true /* aLogIt */);
1168
 
        return rc;
1169
 
    }
1170
 
 
1171
 
    /**
1172
 
     *  This method is the same as #setErrorV() except that it makes sure @a
1173
 
     *  aResultCode doesn't have the error severity bit (31) set when passed
1174
 
     *  down to the created IVirtualBoxErrorInfo object.
1175
 
     *
1176
 
     *  The error severity bit is always cleared by this call, thereof you can
1177
 
     *  use ordinary E_XXX result code constants, for convenience. However, this
1178
 
     *  behavior may be non-standard on some COM platforms.
1179
 
     */
1180
 
    static HRESULT setWarningV(HRESULT aResultCode, const char *aText,
1181
 
                               va_list aArgs)
1182
 
    {
1183
 
        HRESULT rc = VirtualBoxSupportErrorInfoImplBase::setWarning(aResultCode,
1184
 
                                                                    COM_IIDOF(I),
1185
 
                                                                    C::getComponentName(),
1186
 
                                                                    aText,
1187
 
                                                                    aArgs);
1188
 
        return rc;
1189
 
    }
1190
 
 
1191
 
    /**
1192
 
     *  Sets the error information for the current thread.
1193
 
     *  A convenience method that automatically sets the component name
1194
 
     *  (a value of C::getComponentName()), but allows to specify the interface
1195
 
     *  id manually.
1196
 
     *
1197
 
     *  See #setError(HRESULT, const GUID &, const wchar_t *, const char *text, ...)
1198
 
     *  for details.
1199
 
     */
1200
 
    static HRESULT setError(HRESULT aResultCode, const GUID &aIID,
1201
 
                            const char *aText, ...)
1202
 
    {
1203
 
        va_list args;
1204
 
        va_start(args, aText);
1205
 
        HRESULT rc = VirtualBoxSupportErrorInfoImplBase::setError(aResultCode,
1206
 
                                                                  aIID,
1207
 
                                                                  C::getComponentName(),
1208
 
                                                                  aText,
1209
 
                                                                  args,
1210
 
                                                                  true /* aLogIt */);
1211
 
        va_end(args);
1212
 
        return rc;
1213
 
    }
1214
 
 
1215
 
    /**
1216
 
     *  This method is the same as #setError() except that it makes sure @a
1217
 
     *  aResultCode doesn't have the error severity bit (31) set when passed
1218
 
     *  down to the created IVirtualBoxErrorInfo object.
1219
 
     *
1220
 
     *  The error severity bit is always cleared by this call, thereof you can
1221
 
     *  use ordinary E_XXX result code constants, for convenience. However, this
1222
 
     *  behavior may be non-standard on some COM platforms.
1223
 
     */
1224
 
    static HRESULT setWarning(HRESULT aResultCode, const GUID &aIID,
1225
 
                              const char *aText, ...)
1226
 
    {
1227
 
        va_list args;
1228
 
        va_start(args, aText);
1229
 
        HRESULT rc = VirtualBoxSupportErrorInfoImplBase::setWarning(aResultCode,
1230
 
                                                                    aIID,
1231
 
                                                                    C::getComponentName(),
1232
 
                                                                    aText,
1233
 
                                                                    args);
1234
 
        va_end(args);
1235
 
        return rc;
1236
 
    }
1237
 
 
1238
 
    /**
1239
 
     *  Sets the error information for the current thread but doesn't put
1240
 
     *  anything in the release log. This is very useful for avoiding
1241
 
     *  harmless error from causing confusion.
1242
 
     *
1243
 
     *  It is otherwise identical to #setError(HRESULT, const char *text, ...).
1244
 
     */
1245
 
    static HRESULT setErrorNoLog(HRESULT aResultCode, const char *aText, ...)
1246
 
    {
1247
 
        va_list args;
1248
 
        va_start(args, aText);
1249
 
        HRESULT rc = VirtualBoxSupportErrorInfoImplBase::setError(aResultCode,
1250
 
                                                                  COM_IIDOF(I),
1251
 
                                                                  C::getComponentName(),
1252
 
                                                                  aText,
1253
 
                                                                  args,
1254
 
                                                                  false /* aLogIt */);
1255
 
        va_end(args);
1256
 
        return rc;
1257
 
    }
1258
 
 
1259
 
private:
1260
 
 
1261
 
};
1262
 
 
1263
 
 
1264
 
/**
1265
 
 * Base class to track VirtualBoxBaseNEXT chlidren of the component.
1266
 
 *
1267
 
 * This class is a preferrable VirtualBoxBase replacement for components that
1268
 
 * operate with collections of child components. It gives two useful
1269
 
 * possibilities:
1270
 
 *
1271
 
 * <ol><li>
1272
 
 *      Given an IUnknown instance, it's possible to quickly determine
1273
 
 *      whether this instance represents a child object that belongs to the
1274
 
 *      given component, and if so, get a valid VirtualBoxBase pointer to the
1275
 
 *      child object. The returned pointer can be then safely casted to the
1276
 
 *      actual class of the child object (to get access to its "internal"
1277
 
 *      non-interface methods) provided that no other child components implement
1278
 
 *      the same original COM interface IUnknown is queried from.
1279
 
 * </li><li>
1280
 
 *      When the parent object uninitializes itself, it can easily unintialize
1281
 
 *      all its VirtualBoxBase derived children (using their
1282
 
 *      VirtualBoxBase::uninit() implementations). This is done simply by
1283
 
 *      calling the #uninitDependentChildren() method.
1284
 
 * </li></ol>
1285
 
 *
1286
 
 * In order to let the above work, the following must be done:
1287
 
 * <ol><li>
1288
 
 *      When a child object is initialized, it calls #addDependentChild() of
1289
 
 *      its parent to register itself within the list of dependent children.
1290
 
 * </li><li>
1291
 
 *      When the child object it is uninitialized, it calls
1292
 
 *      #removeDependentChild() to unregister itself.
1293
 
 * </li></ol>
1294
 
 *
1295
 
 * Note that if the parent object does not call #uninitDependentChildren() when
1296
 
 * it gets uninitialized, it must call uninit() methods of individual children
1297
 
 * manually to disconnect them; a failure to do so will cause crashes in these
1298
 
 * methods when children get destroyed. The same applies to children not calling
1299
 
 * #removeDependentChild() when getting destroyed.
1300
 
 *
1301
 
 * Note that children added by #addDependentChild() are <b>weakly</b> referenced
1302
 
 * (i.e. AddRef() is not called), so when a child object is deleted externally
1303
 
 * (because it's reference count goes to zero), it will automatically remove
1304
 
 * itself from the map of dependent children provided that it follows the rules
1305
 
 * described here.
1306
 
 *
1307
 
 * Access to the child list is serialized using the #childrenLock() lock handle
1308
 
 * (which defaults to the general object lock handle (see
1309
 
 * VirtualBoxBase::lockHandle()). This lock is used by all add/remove methods of
1310
 
 * this class so be aware of the need to preserve the {parent, child} lock order
1311
 
 * when calling these methods.
1312
 
 *
1313
 
 * Read individual method descriptions to get further information.
1314
 
 *
1315
 
 * @todo This is a VirtualBoxBaseWithChildren equivalent that uses the
1316
 
 *       VirtualBoxBaseNEXT implementation. Will completely supersede
1317
 
 *       VirtualBoxBaseWithChildren after the old VirtualBoxBase implementation
1318
 
 *       has gone.
1319
 
 */
1320
 
class VirtualBoxBaseWithChildrenNEXT : public VirtualBoxBase
1321
 
{
1322
 
public:
1323
 
 
1324
 
    VirtualBoxBaseWithChildrenNEXT()
1325
 
    {}
1326
 
 
1327
 
    virtual ~VirtualBoxBaseWithChildrenNEXT()
1328
 
    {}
1329
 
 
1330
 
    /**
1331
 
     * Lock handle to use when adding/removing child objects from the list of
1332
 
     * children. It is guaranteed that no any other lock is requested in methods
1333
 
     * of this class while holding this lock.
1334
 
     *
1335
 
     * @warning By default, this simply returns the general object's lock handle
1336
 
     *          (see VirtualBoxBase::lockHandle()) which is sufficient for most
1337
 
     *          cases.
1338
 
     */
1339
 
    virtual RWLockHandle *childrenLock() { return lockHandle(); }
1340
 
 
1341
 
    /**
1342
 
     * Adds the given child to the list of dependent children.
1343
 
     *
1344
 
     * Usually gets called from the child's init() method.
1345
 
     *
1346
 
     * @note @a aChild (unless it is in InInit state) must be protected by
1347
 
     *       VirtualBoxBase::AutoCaller to make sure it is not uninitialized on
1348
 
     *       another thread during this method's call.
1349
 
     *
1350
 
     * @note When #childrenLock() is not overloaded (returns the general object
1351
 
     *       lock) and this method is called from under the child's read or
1352
 
     *       write lock, make sure the {parent, child} locking order is
1353
 
     *       preserved by locking the callee (this object) for writing before
1354
 
     *       the child's lock.
1355
 
     *
1356
 
     * @param aChild    Child object to add (must inherit VirtualBoxBase AND
1357
 
     *                  implement some interface).
1358
 
     *
1359
 
     * @note Locks #childrenLock() for writing.
1360
 
     */
1361
 
    template<class C>
1362
 
    void addDependentChild(C *aChild)
1363
 
    {
1364
 
        AssertReturnVoid(aChild != NULL);
1365
 
        doAddDependentChild(ComPtr<IUnknown>(aChild), aChild);
1366
 
    }
1367
 
 
1368
 
    /**
1369
 
     * Equivalent to template <class C> void addDependentChild (C *aChild)
1370
 
     * but takes a ComObjPtr<C> argument.
1371
 
     */
1372
 
    template<class C>
1373
 
    void addDependentChild(const ComObjPtr<C> &aChild)
1374
 
    {
1375
 
        AssertReturnVoid(!aChild.isNull());
1376
 
        doAddDependentChild(ComPtr<IUnknown>(static_cast<C *>(aChild)), aChild);
1377
 
    }
1378
 
 
1379
 
    /**
1380
 
     * Removes the given child from the list of dependent children.
1381
 
     *
1382
 
     * Usually gets called from the child's uninit() method.
1383
 
     *
1384
 
     * Keep in mind that the called (parent) object may be no longer available
1385
 
     * (i.e. may be deleted deleted) after this method returns, so you must not
1386
 
     * call any other parent's methods after that!
1387
 
     *
1388
 
     * @note Locks #childrenLock() for writing.
1389
 
     *
1390
 
     * @note @a aChild (unless it is in InUninit state) must be protected by
1391
 
     *       VirtualBoxBase::AutoCaller to make sure it is not uninitialized on
1392
 
     *       another thread during this method's call.
1393
 
     *
1394
 
     * @note When #childrenLock() is not overloaded (returns the general object
1395
 
     *       lock) and this method is called from under the child's read or
1396
 
     *       write lock, make sure the {parent, child} locking order is
1397
 
     *       preserved by locking the callee (this object) for writing before
1398
 
     *       the child's lock. This is irrelevant when the method is called from
1399
 
     *       under this object's VirtualBoxBaseProto::AutoUninitSpan (i.e. in
1400
 
     *       InUninit state) since in this case no locking is done.
1401
 
     *
1402
 
     * @param aChild    Child object to remove.
1403
 
     *
1404
 
     * @note Locks #childrenLock() for writing.
1405
 
     */
1406
 
    template<class C>
1407
 
    void removeDependentChild(C *aChild)
1408
 
    {
1409
 
        AssertReturnVoid(aChild != NULL);
1410
 
        doRemoveDependentChild(ComPtr<IUnknown>(aChild));
1411
 
    }
1412
 
 
1413
 
    /**
1414
 
     * Equivalent to template <class C> void removeDependentChild (C *aChild)
1415
 
     * but takes a ComObjPtr<C> argument.
1416
 
     */
1417
 
    template<class C>
1418
 
    void removeDependentChild(const ComObjPtr<C> &aChild)
1419
 
    {
1420
 
        AssertReturnVoid(!aChild.isNull());
1421
 
        doRemoveDependentChild(ComPtr<IUnknown>(static_cast<C *>(aChild)));
1422
 
    }
1423
 
 
1424
 
protected:
1425
 
 
1426
 
    void uninitDependentChildren();
1427
 
 
1428
 
    VirtualBoxBase *getDependentChild(const ComPtr<IUnknown> &aUnk);
1429
 
 
1430
 
private:
1431
 
    void doAddDependentChild(IUnknown *aUnk, VirtualBoxBase *aChild);
1432
 
    void doRemoveDependentChild(IUnknown *aUnk);
1433
 
 
1434
 
    typedef std::map<IUnknown*, VirtualBoxBase*> DependentChildren;
1435
 
    DependentChildren mDependentChildren;
1436
 
};
1437
 
 
1438
 
////////////////////////////////////////////////////////////////////////////////
1439
 
 
1440
 
////////////////////////////////////////////////////////////////////////////////
1441
 
 
1442
 
 
1443
 
/// @todo (dmik) remove after we switch to VirtualBoxBaseNEXT completely
 
765
////////////////////////////////////////////////////////////////////////////////
 
766
 
 
767
 
1444
768
/**
1445
769
 *  Simple template that manages data structure allocation/deallocation
1446
770
 *  and supports data pointer sharing (the instance that shares the pointer is
1536
860
    bool mIsShared;
1537
861
};
1538
862
 
1539
 
/// @todo (dmik) remove after we switch to VirtualBoxBaseNEXT completely
1540
863
/**
1541
864
 *  Simple template that enhances Shareable<> and supports data
1542
865
 *  backup/rollback/commit (using the copy constructor of the managed data