VirtualBox

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

最後變更 在這個檔案從3390是 3390,由 vboxsync 提交於 18 年 前

FE/Qt: Fixed builds.

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

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