VirtualBox

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

Last change on this file since 469 was 469, checked in by vboxsync, 18 years ago

Main/XIDL: Added support for the @mod attribute (with 'ptr' the only valud value for now) to declare attributes and method parameters as raw C/C++ pointers (which will make the corresponding methods non-scriptable in e.g. XPCOM but avoid 32/64 bit problems with passing pointers over COM).

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