VirtualBox

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

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

FE/Qt: Cosmetic refactoring.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 17.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 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 mRC; }
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() : mRC (S_OK) {};
246
247#if !defined (Q_OS_WIN32)
248 static nsIComponentManager *gComponentManager;
249 static nsIEventQueue* gEventQ;
250 static ipcIDConnectService *gDConnectService;
251 static PRUint32 gVBoxServerID;
252
253 static XPCOMEventQSocketListener *gSocketListener;
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 mRC;
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 mErrInfo; }
384
385protected:
386
387 /* no arbitrary instance creations */
388 COMBaseWithEI() : COMBase () {};
389
390 void fetchErrorInfo (IUnknown *callee, const GUID *calleeIID) const {
391 mErrInfo.fetchFromCurrentThread (callee, calleeIID);
392 }
393
394 mutable COMErrorInfo mErrInfo;
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() : mIface (NULL) {}
461
462 CInterface (const CInterface &that) : B (that), mIface (that.mIface)
463 {
464 addref (mIface);
465 }
466
467 CInterface (const CUnknown &that);
468
469 CInterface (I *i) : mIface (i) { addref (mIface); }
470
471 virtual ~CInterface() { release (mIface); }
472
473 /* utility methods */
474
475 void createInstance (const CLSID &clsid)
476 {
477 AssertMsg (!mIface, ("Instance is already non-NULL\n"));
478 if (!mIface)
479 {
480#if defined (Q_OS_WIN32)
481 B::mRC = CoCreateInstance (clsid, NULL, CLSCTX_ALL,
482 _ATL_IIDOF (I), (void**) &mIface);
483#else
484 /* first, try to create an instance within the in-proc server
485 * (for compatibility with Win32) */
486 B::mRC = B::gComponentManager->
487 CreateInstance (clsid, nsnull, NS_GET_IID (I), (void**) &mIface);
488 if (FAILED (B::mRC) && B::gDConnectService && B::gVBoxServerID)
489 {
490 /* now try the out-of-proc server if it exists */
491 B::mRC = B::gDConnectService->
492 CreateInstance (B::gVBoxServerID, clsid,
493 NS_GET_IID (I), (void**) &mIface);
494 }
495#endif
496 /* fetch error info, but don't assert if it's missing -- many other
497 * reasons can lead to an error (w/o providing error info), not only
498 * the instance initialization code (that should always provide it) */
499 B::fetchErrorInfo (NULL, NULL);
500 }
501 }
502
503 void attach (I *i)
504 {
505 /* be aware of self (from COM point of view) assignment */
506 I *old_iface = mIface;
507 mIface = i;
508 addref (mIface);
509 release (old_iface);
510 B::mRC = S_OK;
511 };
512
513 void attachUnknown (IUnknown *i)
514 {
515 /* be aware of self (from COM point of view) assignment */
516 I *old_iface = mIface;
517 mIface = NULL;
518 B::mRC = S_OK;
519 if (i)
520#if defined (Q_OS_WIN32)
521 B::mRC = i->QueryInterface (_ATL_IIDOF (I), (void**) &mIface);
522#else
523 B::mRC = i->QueryInterface (NS_GET_IID (I), (void**) &mIface);
524#endif
525 release (old_iface);
526 };
527
528 void detach() { release (mIface); mIface = NULL; }
529
530 bool isNull() const { return mIface == NULL; }
531
532 bool isOk() const { return !isNull() && SUCCEEDED (B::mRC); }
533
534 /* utility operators */
535
536 CInterface &operator= (const CInterface &that)
537 {
538 attach (that.mIface);
539 B::operator= (that);
540 return *this;
541 }
542
543 I *iface() const { return mIface; }
544
545 bool operator== (const CInterface &that) const { return mIface == that.mIface; }
546 bool operator!= (const CInterface &that) const { return mIface != that.mIface; }
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 *mIface;
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 {
569 mIface = NULL;
570 if (that.mIface)
571#if defined (Q_OS_WIN32)
572 mRC = that.mIface->QueryInterface (_ATL_IIDOF (IUnknown), (void**) &mIface);
573#else
574 mRC = that.mIface->QueryInterface (NS_GET_IID (IUnknown), (void**) &mIface);
575#endif
576 if (SUCCEEDED (mRC)) {
577 mRC = that.lastRC();
578 mErrInfo = that.errorInfo();
579 }
580 }
581 /* specialization for CUnknown */
582 CUnknown (const CUnknown &that) : CInterface <IUnknown, COMBaseWithEI> () {
583 mIface = that.mIface;
584 addref (mIface);
585 COMBaseWithEI::operator= (that);
586 }
587
588 template <class C>
589 CUnknown &operator= (const C &that) {
590 /* be aware of self (from COM point of view) assignment */
591 IUnknown *old_iface = mIface;
592 mIface = NULL;
593 mRC = S_OK;
594#if defined (Q_OS_WIN32)
595 if (that.mIface)
596 mRC = that.mIface->QueryInterface (_ATL_IIDOF (IUnknown), (void**) &mIface);
597#else
598 if (that.mIface)
599 mRC = that.mIface->QueryInterface (NS_GET_IID (IUnknown), (void**) &mIface);
600#endif
601 if (SUCCEEDED (mRC)) {
602 mRC = that.lastRC();
603 mErrInfo = that.errorInfo();
604 }
605 release (old_iface);
606 return *this;
607 }
608 /* specialization for CUnknown */
609 CUnknown &operator= (const CUnknown &that) {
610 attach (that.mIface);
611 COMBaseWithEI::operator= (that);
612 return *this;
613 }
614
615 /* @internal Used in wrappers. */
616 IUnknown *&ifaceRef() { return mIface; };
617};
618
619/* inlined CInterface methods that use CUnknown */
620
621template <class I, class B>
622inline CInterface <I, B>::CInterface (const CUnknown &that)
623 : mIface (NULL)
624{
625 attachUnknown (that.iface());
626 if (SUCCEEDED (B::mRC))
627 B::operator= ((B &) that);
628}
629
630template <class I, class B>
631inline CInterface <I, B> &CInterface <I, B>::operator =(const CUnknown &that)
632{
633 attachUnknown (that.iface());
634 if (SUCCEEDED (B::mRC))
635 B::operator= ((B &) that);
636 return *this;
637}
638
639/////////////////////////////////////////////////////////////////////////////
640
641/* include the generated header containing concrete wrapper definitions */
642#include "COMWrappers.h"
643
644#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