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

« back to all changes in this revision

Viewing changes to src/VBox/Frontends/VirtualBox/src/globals/COMDefs.h

  • Committer: Bazaar Package Importer
  • Author(s): Felix Geyer
  • Date: 2009-12-18 16:44:29 UTC
  • mfrom: (0.3.3 upstream) (0.4.6 squeeze)
  • Revision ID: james.westby@ubuntu.com-20091218164429-jd34ccexpv5na11a
Tags: 3.1.2-dfsg-1ubuntu1
* Merge from Debian unstable (LP: #498219), remaining changes:
  - Disable update action
    - debian/patches/u01-disable-update-action.dpatch
  - VirtualBox should go in Accessories, not in System tools (LP: #288590)
    - debian/virtualbox-ose-qt.files/virtualbox-ose.desktop
  - Add Apport hook
    - debian/virtualbox-ose.files/source_virtualbox-ose.py
    - debian/virtualbox-ose.install
  - Add Launchpad integration
    - debian/control
    - debian/lpi-bug.xpm
    - debian/patches/u02-lp-integration.dpatch
* Fixes the following bugs:
  - Kernel module fails to build with Linux >= 2.6.32 (LP: #474625)
  - X.Org drivers need to be rebuilt against X-Server 1.7 (LP: #495935)
  - The *-source packages try to build the kernel modules even though the
    kernel headers aren't available (LP: #473334)
* Replace *-source packages with transitional packages for *-dkms.
* Adapt u01-disable-update-action.dpatch and u02-lp-integration.dpatch for
  new upstream version.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/** @file
 
2
 *
 
3
 * VBox frontends: Qt GUI ("VirtualBox"):
 
4
 * Various COM definitions and COM wrapper class declarations
 
5
 *
 
6
 * This header is used in conjunction with the header generated from
 
7
 * XIDL expressed interface definitions to provide cross-platform Qt-based
 
8
 * interface wrapper classes.
 
9
 */
 
10
 
 
11
/*
 
12
 * Copyright (C) 2006-2008 Sun Microsystems, Inc.
 
13
 *
 
14
 * This file is part of VirtualBox Open Source Edition (OSE), as
 
15
 * available from http://www.virtualbox.org. This file is free software;
 
16
 * you can redistribute it and/or modify it under the terms of the GNU
 
17
 * General Public License (GPL) as published by the Free Software
 
18
 * Foundation, in version 2 as it comes in the "COPYING" file of the
 
19
 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
 
20
 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
 
21
 *
 
22
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
 
23
 * Clara, CA 95054 USA or visit http://www.sun.com if you need
 
24
 * additional information or have any questions.
 
25
 */
 
26
 
 
27
#ifndef __COMDefs_h__
 
28
#define __COMDefs_h__
 
29
 
 
30
/** @defgroup   grp_QT_COM  Qt-COM Support Layer
 
31
 * @{
 
32
 *
 
33
 * The Qt-COM support layer provides a set of definitions and smart classes for
 
34
 * writing simple, clean and platform-independent code to access COM/XPCOM
 
35
 * components through exposed COM interfaces. This layer is based on the
 
36
 * COM/XPCOM Abstraction Layer library (the VBoxCOM glue library defined in
 
37
 * include/VBox/com and implemented in src/VBox/Main/glue).
 
38
 *
 
39
 * ...
 
40
 *
 
41
 * @defgroup   grp_QT_COM_arrays    Arrays
 
42
 * @{
 
43
 *
 
44
 * COM/XPCOM arrays are mapped to QVector objects. QVector templates declared
 
45
 * with a type that corresponds to the COM type of elements in the array using
 
46
 * normal Qt-COM type mapping rules. Here is a code example that demonstrates
 
47
 * how to call interface methods that take and return arrays (this example is
 
48
 * based on examples given in @ref grp_COM_arrays):
 
49
 * @code
 
50
 
 
51
    CSomething component;
 
52
 
 
53
    // ...
 
54
 
 
55
    QVector <LONG> in (3);
 
56
    in [0] = -1;
 
57
    in [1] = -2;
 
58
    in [2] = -3;
 
59
 
 
60
    QVector <LONG> out;
 
61
    QVector <LONG> ret;
 
62
 
 
63
    ret = component.TestArrays (in, out);
 
64
 
 
65
    for (size_t i = 0; i < ret.size(); ++ i)
 
66
        LogFlow (("*** ret[%u]=%d\n", i, ret [i]));
 
67
 
 
68
 * @endcode
 
69
 * @}
 
70
 */
 
71
 
 
72
/* Both VBox/com/assert.h and qglobal.h contain a definition of ASSERT.
 
73
 * Either of them can be already included here, so try to shut them up.  */
 
74
#undef ASSERT
 
75
 
 
76
#include <VBox/com/com.h>
 
77
#include <VBox/com/array.h>
 
78
#include <VBox/com/assert.h>
 
79
 
 
80
#undef ASSERT
 
81
 
 
82
/* Qt includes */
 
83
#include <QString>
 
84
#include <QUuid>
 
85
#include <QVector>
 
86
#include <QMetaType>
 
87
 
 
88
#include <iprt/memory> // for auto_copy_ptr
 
89
 
 
90
/*
 
91
 * Additional COM / XPCOM defines and includes
 
92
 */
 
93
 
 
94
#if !defined (VBOX_WITH_XPCOM)
 
95
 
 
96
#else /* !defined (VBOX_WITH_XPCOM) */
 
97
 
 
98
#include <nsXPCOM.h>
 
99
#include <nsMemory.h>
 
100
#include <nsIComponentManager.h>
 
101
 
 
102
class XPCOMEventQSocketListener;
 
103
 
 
104
#endif /* !defined (VBOX_WITH_XPCOM) */
 
105
 
 
106
 
 
107
/* VirtualBox interfaces declarations */
 
108
#if !defined (VBOX_WITH_XPCOM)
 
109
    #include <VirtualBox.h>
 
110
#else /* !defined (VBOX_WITH_XPCOM) */
 
111
    #include <VirtualBox_XPCOM.h>
 
112
#endif /* !defined (VBOX_WITH_XPCOM) */
 
113
 
 
114
#include "VBoxDefs.h"
 
115
 
 
116
 
 
117
/////////////////////////////////////////////////////////////////////////////
 
118
 
 
119
class CVirtualBoxErrorInfo;
 
120
 
 
121
/** Represents extended error information */
 
122
class COMErrorInfo
 
123
{
 
124
public:
 
125
 
 
126
    COMErrorInfo()
 
127
        : mIsNull (true)
 
128
        , mIsBasicAvailable (false), mIsFullAvailable (false)
 
129
        , mResultCode (S_OK) {}
 
130
 
 
131
    COMErrorInfo (const CVirtualBoxErrorInfo &info) { init (info); }
 
132
 
 
133
    /* the default copy ctor and assignment op are ok */
 
134
 
 
135
    bool isNull() const { return mIsNull; }
 
136
 
 
137
    bool isBasicAvailable() const { return mIsBasicAvailable; }
 
138
    bool isFullAvailable() const { return mIsFullAvailable; }
 
139
 
 
140
    HRESULT resultCode() const { return mResultCode; }
 
141
    QUuid interfaceID() const { return mInterfaceID; }
 
142
    QString component() const { return mComponent; }
 
143
    QString text() const { return mText; }
 
144
 
 
145
    const COMErrorInfo *next() const { return mNext.get(); }
 
146
 
 
147
    QString interfaceName() const { return mInterfaceName; }
 
148
    QUuid calleeIID() const { return mCalleeIID; }
 
149
    QString calleeName() const { return mCalleeName; }
 
150
 
 
151
private:
 
152
 
 
153
    void init (const CVirtualBoxErrorInfo &info);
 
154
    void fetchFromCurrentThread (IUnknown *callee, const GUID *calleeIID);
 
155
 
 
156
    static QString getInterfaceNameFromIID (const QUuid &id);
 
157
 
 
158
    bool mIsNull : 1;
 
159
    bool mIsBasicAvailable : 1;
 
160
    bool mIsFullAvailable : 1;
 
161
 
 
162
    HRESULT mResultCode;
 
163
    QUuid mInterfaceID;
 
164
    QString mComponent;
 
165
    QString mText;
 
166
 
 
167
    cppx::auto_copy_ptr <COMErrorInfo> mNext;
 
168
 
 
169
    QString mInterfaceName;
 
170
    QUuid mCalleeIID;
 
171
    QString mCalleeName;
 
172
 
 
173
    friend class COMBaseWithEI;
 
174
};
 
175
 
 
176
/////////////////////////////////////////////////////////////////////////////
 
177
 
 
178
/**
 
179
 * Base COM class the CInterface template and all wrapper classes are derived
 
180
 * from. Provides common functionality for all COM wrappers.
 
181
 */
 
182
class COMBase
 
183
{
 
184
public:
 
185
 
 
186
    static HRESULT InitializeCOM();
 
187
    static HRESULT CleanupCOM();
 
188
 
 
189
    /**
 
190
     * Returns the result code of the last interface method called by the
 
191
     * wrapper instance or the result of CInterface::createInstance()
 
192
     * operation.
 
193
     */
 
194
    HRESULT lastRC() const { return mRC; }
 
195
 
 
196
#if !defined (VBOX_WITH_XPCOM)
 
197
 
 
198
    /** Converts a GUID value to QUuid */
 
199
    static QUuid ToQUuid (const GUID &id)
 
200
    {
 
201
        return QUuid (id.Data1, id.Data2, id.Data3,
 
202
                      id.Data4[0], id.Data4[1], id.Data4[2], id.Data4[3],
 
203
                      id.Data4[4], id.Data4[5], id.Data4[6], id.Data4[7]);
 
204
    }
 
205
 
 
206
#else /* !defined (VBOX_WITH_XPCOM) */
 
207
 
 
208
    /** Converts a GUID value to QUuid */
 
209
    static QUuid ToQUuid (const nsID &id)
 
210
    {
 
211
        return QUuid (id.m0, id.m1, id.m2,
 
212
                      id.m3[0], id.m3[1], id.m3[2], id.m3[3],
 
213
                      id.m3[4], id.m3[5], id.m3[6], id.m3[7]);
 
214
    }
 
215
 
 
216
#endif /* !defined (VBOX_WITH_XPCOM) */
 
217
 
 
218
    /* Arrays of arbitrary types */
 
219
 
 
220
    template <typename QT, typename CT>
 
221
    static void ToSafeArray (const QVector <QT> &aVec, com::SafeArray <CT> &aArr)
 
222
    {
 
223
        aArr.reset (aVec.size());
 
224
        for (int i = 0; i < aVec.size(); ++i)
 
225
            aArr [i] = static_cast<CT> (aVec.at (i));
 
226
    }
 
227
 
 
228
    template <typename CT, typename QT>
 
229
    static void FromSafeArray (const com::SafeArray <CT> &aArr, QVector <QT> &aVec)
 
230
    {
 
231
        aVec.resize (static_cast<int> (aArr.size()));
 
232
        for (int i = 0; i < aVec.size(); ++i)
 
233
            aVec [i] = static_cast<QT> (aArr [i]);
 
234
    }
 
235
 
 
236
    template <typename QT, typename CT>
 
237
    static void ToSafeArray (const QVector <QT *> &aVec, com::SafeArray <CT *> &aArr)
 
238
    {
 
239
        Q_UNUSED (aVec);
 
240
        Q_UNUSED (aArr);
 
241
        AssertMsgFailedReturnVoid (("No conversion!\n"));
 
242
    }
 
243
 
 
244
    template <typename CT, typename QT>
 
245
    static void FromSafeArray (const com::SafeArray <CT *> &aArr, QVector <QT *> &aVec)
 
246
    {
 
247
        Q_UNUSED (aArr);
 
248
        Q_UNUSED (aVec);
 
249
        AssertMsgFailedReturnVoid (("No conversion!\n"));
 
250
    }
 
251
 
 
252
    /* Arrays of equal types */
 
253
 
 
254
    template <typename T>
 
255
    static void ToSafeArray (const QVector <T> &aVec, com::SafeArray <T> &aArr)
 
256
    {
 
257
        aArr.reset (aVec.size());
 
258
        for (int i = 0; i < aVec.size(); ++i)
 
259
            aArr [i] = aVec.at (i);
 
260
    }
 
261
 
 
262
    template <typename T>
 
263
    static void FromSafeArray (const com::SafeArray <T> &aArr, QVector <T> &aVec)
 
264
    {
 
265
        aVec.resize (static_cast<int> (aArr.size()));
 
266
        for (int i = 0; i < aVec.size(); ++i)
 
267
            aVec [i] = aArr [i];
 
268
    }
 
269
 
 
270
    /* Arrays of strings */
 
271
 
 
272
    static void ToSafeArray (const QVector <QString> &aVec,
 
273
                             com::SafeArray <BSTR> &aArr);
 
274
    static void FromSafeArray (const com::SafeArray <BSTR> &aArr,
 
275
                               QVector <QString> &aVec);
 
276
 
 
277
    /* Arrays of GUID */
 
278
 
 
279
    static void ToSafeArray (const QVector <QUuid> &aVec,
 
280
                             com::SafeGUIDArray &aArr);
 
281
    static void FromSafeArray (const com::SafeGUIDArray &aArr,
 
282
                               QVector <QUuid> &aVec);
 
283
 
 
284
    /* Arrays of enums. Does a cast similar to what ENUMOut does. */
 
285
 
 
286
    template <typename QE, typename CE>
 
287
    static void ToSafeArray (const QVector <QE> &aVec,
 
288
                             com::SafeIfaceArray <CE> &aArr)
 
289
    {
 
290
        aArr.reset (static_cast <int> (aVec.size()));
 
291
        for (int i = 0; i < aVec.size(); ++i)
 
292
            aArr [i] = static_cast <CE> (aVec.at (i));
 
293
    }
 
294
 
 
295
    template <typename CE, typename QE>
 
296
    static void FromSafeArray (const com::SafeIfaceArray <CE> &aArr,
 
297
                               QVector <QE> &aVec)
 
298
    {
 
299
        aVec.resize (static_cast <int> (aArr.size()));
 
300
        for (int i = 0; i < aVec.size(); ++i)
 
301
            aVec [i] = static_cast <QE> (aArr [i]);
 
302
    }
 
303
 
 
304
    /* Arrays of interface pointers. Note: we need a separate pair of names
 
305
     * only because the MSVC8 template matching algorithm is poor and tries to
 
306
     * instantiate a com::SafeIfaceArray <BSTR> (!!!) template otherwise for
 
307
     * *no* reason and fails. Note that it's also not possible to choose the
 
308
     * correct function by specifying template arguments explicitly because then
 
309
     * it starts to try to instantiate the com::SafeArray <I> template for
 
310
     * *no* reason again and fails too. Definitely, broken. Works in GCC like a
 
311
     * charm. */
 
312
 
 
313
    template <class CI, class I>
 
314
    static void ToSafeIfaceArray (const QVector <CI> &aVec,
 
315
                                  com::SafeIfaceArray <I> &aArr)
 
316
    {
 
317
        aArr.reset (static_cast<int> (aVec.size()));
 
318
        for (int i = 0; i < aVec.size(); ++i)
 
319
        {
 
320
            aArr [i] = aVec.at (i).raw();
 
321
            if (aArr [i])
 
322
                aArr [i]->AddRef();
 
323
        }
 
324
    }
 
325
 
 
326
    template <class I, class CI>
 
327
    static void FromSafeIfaceArray (const com::SafeIfaceArray <I> &aArr,
 
328
                                    QVector <CI> &aVec)
 
329
    {
 
330
        aVec.resize (static_cast<int> (aArr.size()));
 
331
        for (int i = 0; i < aVec.size(); ++i)
 
332
            aVec [i].attach (aArr [i]);
 
333
    }
 
334
 
 
335
protected:
 
336
 
 
337
    /* no arbitrary instance creations */
 
338
    COMBase() : mRC (S_OK) {};
 
339
 
 
340
#if defined (VBOX_WITH_XPCOM)
 
341
    static XPCOMEventQSocketListener *sSocketListener;
 
342
#endif
 
343
 
 
344
    /** Adapter to pass QString as input BSTR params */
 
345
    class BSTRIn
 
346
    {
 
347
    public:
 
348
 
 
349
        BSTRIn (const QString &s) : bstr (SysAllocString ((const OLECHAR *)
 
350
            (s.isNull() ? 0 : s.utf16()))) {}
 
351
 
 
352
        ~BSTRIn()
 
353
        {
 
354
            if (bstr)
 
355
                SysFreeString (bstr);
 
356
        }
 
357
 
 
358
        operator BSTR() const { return bstr; }
 
359
 
 
360
    private:
 
361
 
 
362
        BSTR bstr;
 
363
    };
 
364
 
 
365
    /** Adapter to pass QString as output BSTR params */
 
366
    class BSTROut
 
367
    {
 
368
    public:
 
369
 
 
370
        BSTROut (QString &s) : str (s), bstr (0) {}
 
371
 
 
372
        ~BSTROut()
 
373
        {
 
374
            if (bstr) {
 
375
                str = QString::fromUtf16 (bstr);
 
376
                SysFreeString (bstr);
 
377
            }
 
378
        }
 
379
 
 
380
        operator BSTR *() { return &bstr; }
 
381
 
 
382
    private:
 
383
 
 
384
        QString &str;
 
385
        BSTR bstr;
 
386
    };
 
387
 
 
388
    /**
 
389
     * Adapter to pass K* enums as output COM enum params (*_T).
 
390
     *
 
391
     * @param QE    K* enum.
 
392
     * @param CE    COM enum.
 
393
     */
 
394
    template <typename QE, typename CE>
 
395
    class ENUMOut
 
396
    {
 
397
    public:
 
398
 
 
399
        ENUMOut (QE &e) : qe (e), ce ((CE) 0) {}
 
400
        ~ENUMOut() { qe = (QE) ce; }
 
401
        operator CE *() { return &ce; }
 
402
 
 
403
    private:
 
404
 
 
405
        QE &qe;
 
406
        CE ce;
 
407
    };
 
408
 
 
409
#if !defined (VBOX_WITH_XPCOM)
 
410
 
 
411
    /** Adapter to pass QUuid as input GUID params */
 
412
    static GUID GUIDIn (const QUuid &uuid) { return uuid; }
 
413
 
 
414
    /** Adapter to pass QUuid as output GUID params */
 
415
    class GUIDOut
 
416
    {
 
417
    public:
 
418
 
 
419
        GUIDOut (QUuid &id) : uuid (id)
 
420
        {
 
421
            ::memset (&guid, 0, sizeof (GUID));
 
422
        }
 
423
 
 
424
        ~GUIDOut()
 
425
        {
 
426
            uuid = QUuid (
 
427
                guid.Data1, guid.Data2, guid.Data3,
 
428
                guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3],
 
429
                guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7]);
 
430
        }
 
431
 
 
432
        operator GUID *() { return &guid; }
 
433
 
 
434
    private:
 
435
 
 
436
        QUuid &uuid;
 
437
        GUID guid;
 
438
    };
 
439
 
 
440
#else /* !defined (VBOX_WITH_XPCOM) */
 
441
 
 
442
    /** Adapter to pass QUuid as input GUID params */
 
443
    static const nsID &GUIDIn (const QUuid &uuid)
 
444
    {
 
445
        return *(const nsID *) &uuid;
 
446
    }
 
447
 
 
448
    /** Adapter to pass QUuid as output GUID params */
 
449
    class GUIDOut
 
450
    {
 
451
    public:
 
452
 
 
453
        GUIDOut (QUuid &id) : uuid (id), nsid (0) {}
 
454
 
 
455
        ~GUIDOut()
 
456
        {
 
457
            if (nsid)
 
458
            {
 
459
                uuid = QUuid (
 
460
                    nsid->m0, nsid->m1, nsid->m2,
 
461
                    nsid->m3[0], nsid->m3[1], nsid->m3[2], nsid->m3[3],
 
462
                    nsid->m3[4], nsid->m3[5], nsid->m3[6], nsid->m3[7]);
 
463
                nsMemory::Free (nsid);
 
464
            }
 
465
        }
 
466
 
 
467
        operator nsID **() { return &nsid; }
 
468
 
 
469
    private:
 
470
 
 
471
        QUuid &uuid;
 
472
        nsID *nsid;
 
473
    };
 
474
 
 
475
#endif /* !defined (VBOX_WITH_XPCOM) */
 
476
 
 
477
    static void addref (IUnknown *aIface) { if (aIface) aIface->AddRef(); }
 
478
    static void release (IUnknown *aIface) { if (aIface) aIface->Release(); }
 
479
 
 
480
protected:
 
481
 
 
482
    mutable HRESULT mRC;
 
483
 
 
484
    friend class COMErrorInfo;
 
485
};
 
486
 
 
487
/////////////////////////////////////////////////////////////////////////////
 
488
 
 
489
/**
 
490
 * Alternative base class for the CInterface template that adds the errorInfo()
 
491
 * method for providing extended error info about unsuccessful invocation of the
 
492
 * last called interface method.
 
493
 */
 
494
class COMBaseWithEI : public COMBase
 
495
{
 
496
public:
 
497
 
 
498
    /**
 
499
     * Returns error info set by the last unsuccessfully invoked interface
 
500
     * method. Returned error info is useful only if CInterface::lastRC()
 
501
     * represents a failure or a warning (i.e. CInterface::isReallyOk() is
 
502
     * false).
 
503
     */
 
504
    const COMErrorInfo &errorInfo() const { return mErrInfo; }
 
505
 
 
506
protected:
 
507
 
 
508
    /* no arbitrary instance creation */
 
509
    COMBaseWithEI() : COMBase () {};
 
510
 
 
511
    void setErrorInfo (const COMErrorInfo &aErrInfo) { mErrInfo = aErrInfo; }
 
512
 
 
513
    void fetchErrorInfo (IUnknown *aCallee, const GUID *aCalleeIID) const
 
514
    {
 
515
        mErrInfo.fetchFromCurrentThread (aCallee, aCalleeIID);
 
516
    }
 
517
 
 
518
    mutable COMErrorInfo mErrInfo;
 
519
};
 
520
 
 
521
/////////////////////////////////////////////////////////////////////////////
 
522
 
 
523
/**
 
524
 * Simple class that encapsulates the result code and COMErrorInfo.
 
525
 */
 
526
class COMResult
 
527
{
 
528
public:
 
529
 
 
530
    COMResult() : mRC (S_OK) {}
 
531
 
 
532
    /**
 
533
     * Queries the current result code from the given component.
 
534
     */
 
535
    explicit COMResult (const COMBase &aComponent)
 
536
        : mRC (aComponent.lastRC()) {}
 
537
 
 
538
    /**
 
539
     * Queries the current result code and error info from the given component.
 
540
     */
 
541
    COMResult (const COMBaseWithEI &aComponent)
 
542
        : mRC (aComponent.lastRC())
 
543
        , mErrInfo (aComponent.errorInfo()) {}
 
544
 
 
545
    /**
 
546
     * Queries the current result code from the given component.
 
547
     */
 
548
    COMResult &operator= (const COMBase &aComponent)
 
549
    {
 
550
        mRC = aComponent.lastRC();
 
551
        return *this;
 
552
    }
 
553
 
 
554
    /**
 
555
     * Queries the current result code and error info from the given component.
 
556
     */
 
557
    COMResult &operator= (const COMBaseWithEI &aComponent)
 
558
    {
 
559
        mRC = aComponent.lastRC();
 
560
        mErrInfo = aComponent.errorInfo();
 
561
        return *this;
 
562
    }
 
563
 
 
564
    bool isNull() const { return mErrInfo.isNull(); }
 
565
 
 
566
    /**
 
567
     * Returns @c true if the result code represents success (with or without
 
568
     * warnings).
 
569
     */
 
570
    bool isOk() const { return SUCCEEDED (mRC); }
 
571
 
 
572
    /**
 
573
     * Returns @c true if the result code represents success with one or more
 
574
     * warnings.
 
575
     */
 
576
    bool isWarning() const { return SUCCEEDED_WARNING (mRC); }
 
577
 
 
578
    /**
 
579
     * Returns @c true if the result code represents success with no warnings.
 
580
     */
 
581
    bool isReallyOk() const { return mRC == S_OK; }
 
582
 
 
583
    COMErrorInfo errorInfo() const { return mErrInfo; }
 
584
    HRESULT rc() const { return mRC; }
 
585
 
 
586
private:
 
587
 
 
588
    HRESULT mRC;
 
589
    COMErrorInfo mErrInfo;
 
590
};
 
591
 
 
592
/////////////////////////////////////////////////////////////////////////////
 
593
 
 
594
/**
 
595
 * Wrapper template class for all interfaces.
 
596
 *
 
597
 * All interface methods named as they are in the original, i.e. starting
 
598
 * with the capital letter. All utility non-interface methods are named
 
599
 * starting with the small letter. Utility methods should be not normally
 
600
 * called by the end-user client application.
 
601
 *
 
602
 * @param  I    Interface class (i.e. IUnknown/nsISupports derivant).
 
603
 * @param  B    Base class, either COMBase (by default) or COMBaseWithEI.
 
604
 */
 
605
template <class I, class B = COMBase>
 
606
class CInterface : public B
 
607
{
 
608
public:
 
609
 
 
610
    typedef B Base;
 
611
    typedef I Iface;
 
612
 
 
613
    // constructors & destructor
 
614
 
 
615
    CInterface() : mIface (NULL) {}
 
616
 
 
617
    CInterface (const CInterface &that) : B (that), mIface (that.mIface)
 
618
    {
 
619
        addref (mIface);
 
620
    }
 
621
 
 
622
    CInterface (I *aIface) : mIface (aIface) { addref (mIface); }
 
623
 
 
624
    virtual ~CInterface() { release (mIface); }
 
625
 
 
626
    // utility methods
 
627
 
 
628
    void createInstance (const CLSID &aClsId)
 
629
    {
 
630
        AssertMsg (!mIface, ("Instance is already non-NULL\n"));
 
631
        if (!mIface)
 
632
        {
 
633
#if !defined (VBOX_WITH_XPCOM)
 
634
 
 
635
            B::mRC = CoCreateInstance (aClsId, NULL, CLSCTX_ALL,
 
636
                                       _ATL_IIDOF (I), (void **) &mIface);
 
637
 
 
638
#else /* !defined (VBOX_WITH_XPCOM) */
 
639
 
 
640
            nsCOMPtr <nsIComponentManager> manager;
 
641
            B::mRC = NS_GetComponentManager (getter_AddRefs (manager));
 
642
            if (SUCCEEDED (B::mRC))
 
643
                B::mRC = manager->CreateInstance (aClsId, nsnull, NS_GET_IID (I),
 
644
                                                  (void **) &mIface);
 
645
 
 
646
#endif /* !defined (VBOX_WITH_XPCOM) */
 
647
 
 
648
            /* fetch error info, but don't assert if it's missing -- many other
 
649
             * reasons can lead to an error (w/o providing error info), not only
 
650
             * the instance initialization code (that should always provide it) */
 
651
            B::fetchErrorInfo (NULL, NULL);
 
652
        }
 
653
    }
 
654
 
 
655
    /**
 
656
     * Attaches to the given foreign interface pointer by querying the own
 
657
     * interface on it. The operation may fail.
 
658
     */
 
659
    template <class OI>
 
660
    void attach (OI *aIface)
 
661
    {
 
662
        /* be aware of self assignment */
 
663
        addref (aIface);
 
664
        release (mIface);
 
665
        if (aIface)
 
666
        {
 
667
            mIface = NULL;
 
668
#if !defined (VBOX_WITH_XPCOM)
 
669
            B::mRC = aIface->QueryInterface (_ATL_IIDOF (I), (void **) &mIface);
 
670
#else /* !defined (VBOX_WITH_XPCOM) */
 
671
            B::mRC = aIface->QueryInterface (NS_GET_IID (I), (void **) &mIface);
 
672
#endif /* !defined (VBOX_WITH_XPCOM) */
 
673
        }
 
674
        else
 
675
        {
 
676
            mIface = NULL;
 
677
            B::mRC = S_OK;
 
678
        }
 
679
    };
 
680
 
 
681
    /** Specialization of attach() for our own interface I. Never fails. */
 
682
    void attach (I *aIface)
 
683
    {
 
684
        /* be aware of self assignment */
 
685
        addref (aIface);
 
686
        release (mIface);
 
687
        mIface = aIface;
 
688
        B::mRC = S_OK;
 
689
    };
 
690
 
 
691
    /** Detaches from the underlying interface pointer. */
 
692
    void detach() { release (mIface); mIface = NULL; }
 
693
 
 
694
    /** Returns @c true if not attached to any interface pointer. */
 
695
    bool isNull() const { return mIface == NULL; }
 
696
 
 
697
    /**
 
698
     * Returns @c true if the result code represents success (with or without
 
699
     * warnings).
 
700
     */
 
701
    bool isOk() const { return !isNull() && SUCCEEDED (B::mRC); }
 
702
 
 
703
    /**
 
704
     * Returns @c true if the result code represents success with one or more
 
705
     * warnings.
 
706
     */
 
707
    bool isWarning() const { return !isNull() && SUCCEEDED_WARNING (B::mRC); }
 
708
 
 
709
    /**
 
710
     * Returns @c true if the result code represents success with no warnings.
 
711
     */
 
712
    bool isReallyOk() const { return !isNull() && B::mRC == S_OK; }
 
713
 
 
714
    // utility operators
 
715
 
 
716
    CInterface &operator= (const CInterface &that)
 
717
    {
 
718
        attach (that.mIface);
 
719
        B::operator= (that);
 
720
        return *this;
 
721
    }
 
722
 
 
723
    CInterface &operator= (I *aIface)
 
724
    {
 
725
        attach (aIface);
 
726
        return *this;
 
727
    }
 
728
 
 
729
    /**
 
730
     * Returns the raw interface pointer. Not intended to be used for anything
 
731
     * else but in generated wrappers and for debugging. You've been warned.
 
732
     */
 
733
    I *raw() const { return mIface; }
 
734
 
 
735
    bool operator== (const CInterface &that) const { return mIface == that.mIface; }
 
736
    bool operator!= (const CInterface &that) const { return mIface != that.mIface; }
 
737
 
 
738
protected:
 
739
 
 
740
    mutable I *mIface;
 
741
};
 
742
 
 
743
/////////////////////////////////////////////////////////////////////////////
 
744
 
 
745
class CUnknown : public CInterface <IUnknown, COMBaseWithEI>
 
746
{
 
747
public:
 
748
 
 
749
    typedef CInterface <IUnknown, COMBaseWithEI> Base;
 
750
 
 
751
    CUnknown() {}
 
752
 
 
753
    /** Creates an instance given another CInterface-based instance. */
 
754
    template <class OI, class OB>
 
755
    explicit CUnknown (const CInterface <OI, OB> &that)
 
756
    {
 
757
        attach (that.mIface);
 
758
        if (SUCCEEDED (mRC))
 
759
        {
 
760
            /* preserve old error info if any */
 
761
            mRC = that.lastRC();
 
762
            setErrorInfo (that.errorInfo());
 
763
        }
 
764
    }
 
765
 
 
766
    /** Constructor specialization for IUnknown. */
 
767
    CUnknown (const CUnknown &that) : Base (that) {}
 
768
 
 
769
    /** Creates an instance given a foreign interface pointer. */
 
770
    template <class OI>
 
771
    explicit CUnknown (OI *aIface)
 
772
    {
 
773
        attach (aIface);
 
774
    }
 
775
 
 
776
    /** Constructor specialization for IUnknown. */
 
777
    explicit CUnknown (IUnknown *aIface) : Base (aIface) {}
 
778
 
 
779
    /** Assigns from another CInterface-based instance. */
 
780
    template <class OI, class OB>
 
781
    CUnknown &operator= (const CInterface <OI, OB> &that)
 
782
    {
 
783
        attach (that.mIface);
 
784
        if (SUCCEEDED (mRC))
 
785
        {
 
786
            /* preserve old error info if any */
 
787
            mRC = that.lastRC();
 
788
            setErrorInfo (that.errorInfo());
 
789
        }
 
790
        return *this;
 
791
    }
 
792
 
 
793
    /** Assignment specialization for CUnknown. */
 
794
    CUnknown &operator= (const CUnknown &that)
 
795
    {
 
796
        Base::operator= (that);
 
797
        return *this;
 
798
    }
 
799
 
 
800
    /** Assigns from a foreign interface pointer. */
 
801
    template <class OI>
 
802
    CUnknown &operator= (OI *aIface)
 
803
    {
 
804
        attach (aIface);
 
805
        return *this;
 
806
    }
 
807
 
 
808
    /** Assignment specialization for IUnknown. */
 
809
    CUnknown &operator= (IUnknown *aIface)
 
810
    {
 
811
        Base::operator= (aIface);
 
812
        return *this;
 
813
    }
 
814
 
 
815
    /* @internal Used in generated wrappers. Never use directly. */
 
816
    IUnknown *&rawRef() { return mIface; };
 
817
};
 
818
 
 
819
/////////////////////////////////////////////////////////////////////////////
 
820
 
 
821
/* include the generated header containing concrete wrapper definitions */
 
822
#include "COMWrappers.h"
 
823
 
 
824
/** @} */
 
825
 
 
826
#endif // __COMDefs_h__