VirtualBox

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

Last change on this file since 70 was 1, checked in by vboxsync, 55 years ago

import

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

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