~ubuntu-branches/ubuntu/trusty/virtualbox-ose/trusty

« back to all changes in this revision

Viewing changes to src/VBox/Frontends/VirtualBox/include/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__