VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox/include/COMDefs.h@ 2997

Last change on this file since 2997 was 2981, checked in by vboxsync, 17 years ago

InnoTek -> innotek: all the headers and comments.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 15.8 KB
Line 
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-2007 innotek GmbH
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 as published by the Free Software Foundation,
18 * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
19 * distribution. VirtualBox OSE is distributed in the hope that it will
20 * be useful, but WITHOUT ANY WARRANTY of any kind.
21 *
22 * If you received this file as part of a commercial VirtualBox
23 * distribution, then only the terms of your commercial VirtualBox
24 * license agreement apply instead of the previous paragraph.
25 */
26
27#ifndef __COMDefs_h__
28#define __COMDefs_h__
29
30
31/* Both VBox/com/assert.h and qglobal.h contain a definition of ASSERT.
32 * Either of them can be already included here, so try to shut them up. */
33#undef ASSERT
34
35#include <VBox/com/com.h>
36
37#undef ASSERT
38
39#include <qglobal.h>
40#include <qstring.h>
41#include <quuid.h>
42
43#include <iprt/memory> // for auto_copy_ptr
44
45/*
46 * Additional COM / XPCOM defines and includes
47 */
48
49#define IN_BSTRPARAM INPTR BSTR
50#define IN_GUIDPARAM INPTR GUIDPARAM
51
52#if !defined (VBOX_WITH_XPCOM)
53
54#else /* !defined (VBOX_WITH_XPCOM) */
55
56#include <nsXPCOM.h>
57#include <nsMemory.h>
58#include <nsIComponentManager.h>
59
60class XPCOMEventQSocketListener;
61
62#endif /* !defined (VBOX_WITH_XPCOM) */
63
64
65/* VirtualBox interfaces declarations */
66#if !defined (VBOX_WITH_XPCOM)
67 #include <VirtualBox.h>
68#else /* !defined (VBOX_WITH_XPCOM) */
69 #include <VirtualBox_XPCOM.h>
70#endif /* !defined (VBOX_WITH_XPCOM) */
71
72#include "VBoxDefs.h"
73
74
75/////////////////////////////////////////////////////////////////////////////
76
77class CVirtualBoxErrorInfo;
78
79/** Represents extended error information */
80class COMErrorInfo
81{
82public:
83
84 COMErrorInfo()
85 : mIsNull (true)
86 , mIsBasicAvailable (false), mIsFullAvailable (false)
87 , mResultCode (S_OK) {}
88
89 COMErrorInfo (const CVirtualBoxErrorInfo &info) { init (info); }
90
91 /* the default copy ctor and assignment op are ok */
92
93 bool isNull() const { return mIsNull; }
94
95 bool isBasicAvailable() const { return mIsBasicAvailable; }
96 bool isFullAvailable() const { return mIsFullAvailable; }
97
98 HRESULT resultCode() const { return mResultCode; }
99 QUuid interfaceID() const { return mInterfaceID; }
100 QString component() const { return mComponent; }
101 QString text() const { return mText; }
102
103 const COMErrorInfo *next() const { return mNext.get(); }
104
105 QString interfaceName() const { return mInterfaceName; }
106 QUuid calleeIID() const { return mCalleeIID; }
107 QString calleeName() const { return mCalleeName; }
108
109private:
110
111 void init (const CVirtualBoxErrorInfo &info);
112 void fetchFromCurrentThread (IUnknown *callee, const GUID *calleeIID);
113
114 static QString getInterfaceNameFromIID (const QUuid &id);
115
116 bool mIsNull : 1;
117 bool mIsBasicAvailable : 1;
118 bool mIsFullAvailable : 1;
119
120 HRESULT mResultCode;
121 QUuid mInterfaceID;
122 QString mComponent;
123 QString mText;
124
125 cppx::auto_copy_ptr <COMErrorInfo> mNext;
126
127 QString mInterfaceName;
128 QUuid mCalleeIID;
129 QString mCalleeName;
130
131 friend class COMBaseWithEI;
132};
133
134/////////////////////////////////////////////////////////////////////////////
135
136/**
137 * Base COM class the CInterface template and all wrapper classes are derived
138 * from. Provides common functionality for all COM wrappers.
139 */
140class COMBase
141{
142public:
143
144 static HRESULT initializeCOM();
145 static HRESULT cleanupCOM();
146
147#if !defined (VBOX_WITH_XPCOM)
148
149 /** Converts a GUID value to QUuid */
150 static QUuid toQUuid (const GUID &id)
151 {
152 return QUuid (id.Data1, id.Data2, id.Data3,
153 id.Data4[0], id.Data4[1], id.Data4[2], id.Data4[3],
154 id.Data4[4], id.Data4[5], id.Data4[6], id.Data4[7]);
155 }
156
157#else /* !defined (VBOX_WITH_XPCOM) */
158
159 /** Converts a GUID value to QUuid */
160 static QUuid toQUuid (const nsID &id)
161 {
162 return QUuid (id.m0, id.m1, id.m2,
163 id.m3[0], id.m3[1], id.m3[2], id.m3[3],
164 id.m3[4], id.m3[5], id.m3[6], id.m3[7]);
165 }
166
167#endif /* !defined (VBOX_WITH_XPCOM) */
168
169 /**
170 * Returns the result code of the last interface method called
171 * by the wrapper instance or the result of CInterface::createInstance()
172 * operation.
173 */
174 HRESULT lastRC() const { return mRC; }
175
176 /**
177 * Returns error info set by the last unsuccessfully invoked interface
178 * method. Returned error info is useful only if CInterface::lastRC()
179 * represents a failure (i.e. CInterface::isOk() is false).
180 */
181 virtual COMErrorInfo errorInfo() const { return COMErrorInfo(); }
182
183protected:
184
185 /* no arbitrary instance creations */
186 COMBase() : mRC (S_OK) {};
187
188#if defined (VBOX_WITH_XPCOM)
189 static XPCOMEventQSocketListener *sSocketListener;
190#endif
191
192 /** Adapter to pass QString as input BSTR params */
193 class BSTRIn
194 {
195 public:
196
197 BSTRIn (const QString &s) : bstr (SysAllocString ((const OLECHAR *) s.ucs2())) {}
198
199 ~BSTRIn()
200 {
201 if (bstr)
202 SysFreeString (bstr);
203 }
204
205 operator BSTR() const { return bstr; }
206
207 private:
208
209 BSTR bstr;
210 };
211
212 /** Adapter to pass QString as output BSTR params */
213 class BSTROut
214 {
215 public:
216
217 BSTROut (QString &s) : str (s), bstr (0) {}
218
219 ~BSTROut()
220 {
221 if (bstr) {
222 str = QString::fromUcs2 (bstr);
223 SysFreeString (bstr);
224 }
225 }
226
227 operator BSTR *() { return &bstr; }
228
229 private:
230
231 QString &str;
232 BSTR bstr;
233 };
234
235 /** Adapter to pass CEnums enums as output VirtualBox enum params (*_T) */
236 template <typename CE, typename VE>
237 class ENUMOut
238 {
239 public:
240
241 ENUMOut (CE &e) : ce (e), ve ((VE) 0) {}
242 ~ENUMOut() { ce = (CE) ve; }
243 operator VE *() { return &ve; }
244
245 private:
246
247 CE &ce;
248 VE ve;
249 };
250
251#if !defined (VBOX_WITH_XPCOM)
252
253 /** Adapter to pass QUuid as input GUID params */
254 static GUID GUIDIn (const QUuid &uuid) { return uuid; }
255
256 /** Adapter to pass QUuid as output GUID params */
257 class GUIDOut
258 {
259 public:
260
261 GUIDOut (QUuid &id) : uuid (id)
262 {
263 ::memset (&guid, 0, sizeof (GUID));
264 }
265
266 ~GUIDOut()
267 {
268 uuid = QUuid (
269 guid.Data1, guid.Data2, guid.Data3,
270 guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3],
271 guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7]);
272 }
273
274 operator GUID *() { return &guid; }
275
276 private:
277
278 QUuid &uuid;
279 GUID guid;
280 };
281
282#else /* !defined (VBOX_WITH_XPCOM) */
283
284 /** Adapter to pass QUuid as input GUID params */
285 static const nsID &GUIDIn (const QUuid &uuid)
286 {
287 return *(const nsID *) &uuid;
288 }
289
290 /** Adapter to pass QUuid as output GUID params */
291 class GUIDOut
292 {
293 public:
294
295 GUIDOut (QUuid &id) : uuid (id), nsid (0) {}
296
297 ~GUIDOut()
298 {
299 if (nsid)
300 {
301 uuid = QUuid (
302 nsid->m0, nsid->m1, nsid->m2,
303 nsid->m3[0], nsid->m3[1], nsid->m3[2], nsid->m3[3],
304 nsid->m3[4], nsid->m3[5], nsid->m3[6], nsid->m3[7]);
305 nsMemory::Free (nsid);
306 }
307 }
308
309 operator nsID **() { return &nsid; }
310
311 private:
312
313 QUuid &uuid;
314 nsID *nsid;
315 };
316
317#endif /* !defined (VBOX_WITH_XPCOM) */
318
319 void fetchErrorInfo (IUnknown * /*callee*/, const GUID * /*calleeIID*/) const {}
320
321 mutable HRESULT mRC;
322
323 friend class COMErrorInfo;
324};
325
326/////////////////////////////////////////////////////////////////////////////
327
328/**
329 * Alternative base class for the CInterface template that adds
330 * the errorInfo() method for providing extended error info about
331 * unsuccessful invocation of the last called interface method.
332 */
333class COMBaseWithEI : public COMBase
334{
335public:
336
337 /**
338 * Returns error info set by the last unsuccessfully invoked interface
339 * method. Returned error info is useful only if CInterface::lastRC()
340 * represents a failure (i.e. CInterface::isOk() is false).
341 */
342 COMErrorInfo errorInfo() const { return mErrInfo; }
343
344protected:
345
346 /* no arbitrary instance creations */
347 COMBaseWithEI() : COMBase () {};
348
349 void fetchErrorInfo (IUnknown *callee, const GUID *calleeIID) const
350 {
351 mErrInfo.fetchFromCurrentThread (callee, calleeIID);
352 }
353
354 mutable COMErrorInfo mErrInfo;
355};
356
357/////////////////////////////////////////////////////////////////////////////
358
359/**
360 * Simple class that encapsulates the result code and COMErrorInfo.
361 */
362class COMResult
363{
364public:
365
366 COMResult() : mRC (S_OK) {}
367
368 /** Queries the current result code and error info from the given component */
369 COMResult (const COMBase &aComponent)
370 {
371 mErrInfo = aComponent.errorInfo();
372 mRC = aComponent.lastRC();
373 }
374
375 /** Queries the current result code and error info from the given component */
376 COMResult &operator= (const COMBase &aComponent)
377 {
378 mErrInfo = aComponent.errorInfo();
379 mRC = aComponent.lastRC();
380 return *this;
381 }
382
383 bool isNull() const { return mErrInfo.isNull(); }
384 bool isOk() const { return mErrInfo.isNull() && SUCCEEDED (mRC); }
385
386 COMErrorInfo errorInfo() const { return mErrInfo; }
387 HRESULT rc() const { return mRC; }
388
389private:
390
391 COMErrorInfo mErrInfo;
392 HRESULT mRC;
393};
394
395/////////////////////////////////////////////////////////////////////////////
396
397class CUnknown;
398
399/**
400 * Wrapper template class for all interfaces.
401 *
402 * All interface methods named as they are in the original, i.e. starting
403 * with the capital letter. All utility non-interface methods are named
404 * starting with the small letter. Utility methods should be not normally
405 * called by the end-user client application.
406 *
407 * @param I interface class (i.e. IUnknown/nsISupports derivant)
408 * @param B base class, either COMBase (by default) or COMBaseWithEI
409 */
410template <class I, class B = COMBase>
411class CInterface : public B
412{
413public:
414
415 typedef B Base;
416 typedef I Iface;
417
418 /* constructors & destructor */
419
420 CInterface() : mIface (NULL) {}
421
422 CInterface (const CInterface &that) : B (that), mIface (that.mIface)
423 {
424 addref (mIface);
425 }
426
427 CInterface (const CUnknown &that);
428
429 CInterface (I *i) : mIface (i) { addref (mIface); }
430
431 virtual ~CInterface() { release (mIface); }
432
433 /* utility methods */
434
435 void createInstance (const CLSID &clsid)
436 {
437 AssertMsg (!mIface, ("Instance is already non-NULL\n"));
438 if (!mIface)
439 {
440#if !defined (VBOX_WITH_XPCOM)
441
442 B::mRC = CoCreateInstance (clsid, NULL, CLSCTX_ALL,
443 _ATL_IIDOF (I), (void **) &mIface);
444
445#else /* !defined (VBOX_WITH_XPCOM) */
446
447 nsCOMPtr <nsIComponentManager> manager;
448 B::mRC = NS_GetComponentManager (getter_AddRefs (manager));
449 if (SUCCEEDED (B::mRC))
450 B::mRC = manager->CreateInstance (clsid, nsnull, NS_GET_IID (I),
451 (void **) &mIface);
452
453#endif /* !defined (VBOX_WITH_XPCOM) */
454
455 /* fetch error info, but don't assert if it's missing -- many other
456 * reasons can lead to an error (w/o providing error info), not only
457 * the instance initialization code (that should always provide it) */
458 B::fetchErrorInfo (NULL, NULL);
459 }
460 }
461
462 void attach (I *i)
463 {
464 /* be aware of self (from COM point of view) assignment */
465 I *old_iface = mIface;
466 mIface = i;
467 addref (mIface);
468 release (old_iface);
469 B::mRC = S_OK;
470 };
471
472 void attachUnknown (IUnknown *i)
473 {
474 /* be aware of self (from COM point of view) assignment */
475 I *old_iface = mIface;
476 mIface = NULL;
477 B::mRC = S_OK;
478 if (i)
479#if !defined (VBOX_WITH_XPCOM)
480 B::mRC = i->QueryInterface (_ATL_IIDOF (I), (void **) &mIface);
481#else /* !defined (VBOX_WITH_XPCOM) */
482 B::mRC = i->QueryInterface (NS_GET_IID (I), (void **) &mIface);
483#endif /* !defined (VBOX_WITH_XPCOM) */
484 release (old_iface);
485 };
486
487 void detach() { release (mIface); mIface = NULL; }
488
489 bool isNull() const { return mIface == NULL; }
490
491 bool isOk() const { return !isNull() && SUCCEEDED (B::mRC); }
492
493 /* utility operators */
494
495 CInterface &operator= (const CInterface &that)
496 {
497 attach (that.mIface);
498 B::operator= (that);
499 return *this;
500 }
501
502 I *iface() const { return mIface; }
503
504 bool operator== (const CInterface &that) const { return mIface == that.mIface; }
505 bool operator!= (const CInterface &that) const { return mIface != that.mIface; }
506
507 CInterface &operator= (const CUnknown &that);
508
509protected:
510
511 static void addref (I *i) { if (i) i->AddRef(); }
512 static void release (I *i) { if (i) i->Release(); }
513
514 mutable I *mIface;
515};
516
517/////////////////////////////////////////////////////////////////////////////
518
519class CUnknown : public CInterface <IUnknown, COMBaseWithEI>
520{
521public:
522
523 CUnknown() : CInterface <IUnknown, COMBaseWithEI> () {}
524
525 template <class C>
526 explicit CUnknown (const C &that)
527 {
528 mIface = NULL;
529 if (that.mIface)
530#if !defined (VBOX_WITH_XPCOM)
531 mRC = that.mIface->QueryInterface (_ATL_IIDOF (IUnknown), (void**) &mIface);
532#else /* !defined (VBOX_WITH_XPCOM) */
533 mRC = that.mIface->QueryInterface (NS_GET_IID (IUnknown), (void**) &mIface);
534#endif /* !defined (VBOX_WITH_XPCOM) */
535 if (SUCCEEDED (mRC))
536 {
537 mRC = that.lastRC();
538 mErrInfo = that.errorInfo();
539 }
540 }
541
542 /* specialization for CUnknown */
543 CUnknown (const CUnknown &that) : CInterface <IUnknown, COMBaseWithEI> ()
544 {
545 mIface = that.mIface;
546 addref (mIface);
547 COMBaseWithEI::operator= (that);
548 }
549
550 template <class C>
551 CUnknown &operator= (const C &that)
552 {
553 /* be aware of self (from COM point of view) assignment */
554 IUnknown *old_iface = mIface;
555 mIface = NULL;
556 mRC = S_OK;
557#if !defined (VBOX_WITH_XPCOM)
558 if (that.mIface)
559 mRC = that.mIface->QueryInterface (_ATL_IIDOF (IUnknown), (void**) &mIface);
560#else /* !defined (VBOX_WITH_XPCOM) */
561 if (that.mIface)
562 mRC = that.mIface->QueryInterface (NS_GET_IID (IUnknown), (void**) &mIface);
563#endif /* !defined (VBOX_WITH_XPCOM) */
564 if (SUCCEEDED (mRC))
565 {
566 mRC = that.lastRC();
567 mErrInfo = that.errorInfo();
568 }
569 release (old_iface);
570 return *this;
571 }
572
573 /* specialization for CUnknown */
574 CUnknown &operator= (const CUnknown &that)
575 {
576 attach (that.mIface);
577 COMBaseWithEI::operator= (that);
578 return *this;
579 }
580
581 /* @internal Used in wrappers. */
582 IUnknown *&ifaceRef() { return mIface; };
583};
584
585/* inlined CInterface methods that use CUnknown */
586
587template <class I, class B>
588inline CInterface <I, B>::CInterface (const CUnknown &that)
589 : mIface (NULL)
590{
591 attachUnknown (that.iface());
592 if (SUCCEEDED (B::mRC))
593 B::operator= ((B &) that);
594}
595
596template <class I, class B>
597inline CInterface <I, B> &CInterface <I, B>::operator =(const CUnknown &that)
598{
599 attachUnknown (that.iface());
600 if (SUCCEEDED (B::mRC))
601 B::operator= ((B &) that);
602 return *this;
603}
604
605/////////////////////////////////////////////////////////////////////////////
606
607/* include the generated header containing concrete wrapper definitions */
608#include "COMWrappers.h"
609
610#endif // __COMDefs_h__
Note: See TracBrowser for help on using the repository browser.

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