VirtualBox

source: vbox/trunk/include/VBox/com/defs.h@ 28945

Last change on this file since 28945 was 28945, checked in by vboxsync, 15 years ago

Main/VirtualBox: Sketched out automatic removal of dead callbacks. No functional yet as the specific status codes have not been found. :-)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 23.0 KB
Line 
1/** @file
2 * MS COM / XPCOM Abstraction Layer:
3 * Common definitions
4 */
5
6/*
7 * Copyright (C) 2006-2010 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 */
26
27#ifndef ___VBox_com_defs_h
28#define ___VBox_com_defs_h
29
30/* Make sure all the stdint.h macros are included - must come first! */
31#ifndef __STDC_LIMIT_MACROS
32# define __STDC_LIMIT_MACROS
33#endif
34#ifndef __STDC_CONSTANT_MACROS
35# define __STDC_CONSTANT_MACROS
36#endif
37
38#if defined (RT_OS_OS2)
39
40#if defined(RT_MAX) && RT_MAX != 22
41# error RT_MAX already defined by <iprt/cdefs.h>! Make sure <VBox/com/defs.h> \
42 is included before it.
43#endif
44
45/* Make sure OS/2 Toolkit headers are pulled in to have BOOL/ULONG/etc. typedefs
46 * already defined in order to be able to redefine them using #define. It's
47 * also important to do it before iprt/cdefs.h, otherwise we'll lose RT_MAX in
48 * all code that uses COM Glue. */
49#define INCL_BASE
50#define INCL_PM
51#include <os2.h>
52
53/* OS/2 Toolkit defines TRUE and FALSE */
54#undef FALSE
55#undef TRUE
56
57#endif /* defined (RT_OS_OS2) */
58
59/* Include iprt/types.h (which also includes iprt/types.h) now to make sure iprt
60 * gets to stdint.h first, otherwise a system/xpcom header might beat us and
61 * we'll be without the macros that are optional in C++. */
62#include <iprt/types.h>
63
64#if !defined (VBOX_WITH_XPCOM)
65
66#if defined (RT_OS_WINDOWS)
67
68// Windows COM
69/////////////////////////////////////////////////////////////////////////////
70
71#include <objbase.h>
72#ifndef VBOX_COM_NO_ATL
73# include <atlbase.h>
74#include <atlcom.h>
75#endif
76
77#define NS_DECL_ISUPPORTS
78#define NS_IMPL_ISUPPORTS1_CI(a, b)
79
80/* these are XPCOM only, one for every interface implemented */
81#define NS_DECL_ISUPPORTS
82
83/** Returns @c true if @a rc represents a warning result code */
84#define SUCCEEDED_WARNING(rc) (SUCCEEDED (rc) && (rc) != S_OK)
85
86/** Tests is a COM result code indicates that the process implementing the
87 * interface is dead. */
88#define FAILED_DEAD_INTERFACE(rc) (false) /**< @todo */
89
90/** Immutable BSTR string */
91typedef const OLECHAR *CBSTR;
92
93/** Input BSTR argument of interface method declaration. */
94#define IN_BSTR BSTR
95
96/** Input GUID argument of interface method declaration. */
97#define IN_GUID GUID
98/** Output GUID argument of interface method declaration. */
99#define OUT_GUID GUID*
100
101/** Makes the name of the getter interface function (n must be capitalized). */
102#define COMGETTER(n) get_##n
103/** Makes the name of the setter interface function (n must be capitalized). */
104#define COMSETTER(n) put_##n
105
106/**
107 * Declares an input safearray parameter in the COM method implementation. Also
108 * used to declare the COM attribute setter parameter. Corresponds to either of
109 * the following XIDL definitions:
110 * <pre>
111 * <param name="arg" ... dir="in" safearray="yes"/>
112 * ...
113 * <attribute name="arg" ... safearray="yes"/>
114 * </pre>
115 *
116 * The method implementation should use the com::SafeArray helper class to work
117 * with parameters declared using this define.
118 *
119 * @param aType Array element type.
120 * @param aArg Parameter/attribute name.
121 */
122#define ComSafeArrayIn(aType, aArg) SAFEARRAY **aArg
123
124/**
125 * Expands to @true if the given input safearray parameter is a "null pointer"
126 * which makes it impossible to use it for reading safearray data.
127 */
128#define ComSafeArrayInIsNull(aArg) ((aArg) == NULL || *(aArg) == NULL)
129
130/**
131 * Wraps the given parameter name to generate an expression that is suitable for
132 * passing the parameter to functions that take input safearray parameters
133 * declared using the ComSafeArrayIn marco.
134 *
135 * @param aArg Parameter name to wrap. The given parameter must be declared
136 * within the calling function using the ComSafeArrayIn macro.
137 */
138#define ComSafeArrayInArg(aArg) aArg
139
140/**
141 * Declares an output safearray parameter in the COM method implementation. Also
142 * used to declare the COM attribute getter parameter. Corresponds to either of
143 * the following XIDL definitions:
144 * <pre>
145 * <param name="arg" ... dir="out" safearray="yes"/>
146 * <param name="arg" ... dir="return" safearray="yes"/>
147 * ...
148 * <attribute name="arg" ... safearray="yes"/>
149 * </pre>
150 *
151 * The method implementation should use the com::SafeArray helper class to work
152 * with parameters declared using this define.
153 *
154 * @param aType Array element type.
155 * @param aArg Parameter/attribute name.
156 */
157#define ComSafeArrayOut(aType, aArg) SAFEARRAY **aArg
158
159/**
160 * Expands to @true if the given output safearray parameter is a "null pointer"
161 * which makes it impossible to use it for returning a safearray.
162 */
163#define ComSafeArrayOutIsNull(aArg) ((aArg) == NULL)
164
165/**
166 * Wraps the given parameter name to generate an expression that is suitable for
167 * passing the parameter to functions that take output safearray parameters
168 * declared using the ComSafeArrayOut marco.
169 *
170 * @param aArg Parameter name to wrap. The given parameter must be declared
171 * within the calling function using the ComSafeArrayOut macro.
172 */
173#define ComSafeArrayOutArg(aArg) aArg
174
175/**
176 * Version of ComSafeArrayIn for GUID.
177 * @param aArg Parameter name to wrap.
178 */
179#define ComSafeGUIDArrayIn(aArg) SAFEARRAY **aArg
180
181/**
182 * Version of ComSafeArrayInIsNull for GUID.
183 * @param aArg Parameter name to wrap.
184 */
185#define ComSafeGUIDArrayInIsNull(aArg) ComSafeArrayInIsNull (aArg)
186
187/**
188 * Version of ComSafeArrayInArg for GUID.
189 * @param aArg Parameter name to wrap.
190 */
191#define ComSafeGUIDArrayInArg(aArg) ComSafeArrayInArg (aArg)
192
193/**
194 * Version of ComSafeArrayOut for GUID.
195 * @param aArg Parameter name to wrap.
196 */
197#define ComSafeGUIDArrayOut(aArg) SAFEARRAY **aArg
198
199/**
200 * Version of ComSafeArrayOutIsNull for GUID.
201 * @param aArg Parameter name to wrap.
202 */
203#define ComSafeGUIDArrayOutIsNull(aArg) ComSafeArrayOutIsNull (aArg)
204
205/**
206 * Version of ComSafeArrayOutArg for GUID.
207 * @param aArg Parameter name to wrap.
208 */
209#define ComSafeGUIDArrayOutArg(aArg) ComSafeArrayOutArg (aArg)
210
211/**
212 * Returns the const reference to the IID (i.e., |const GUID &|) of the given
213 * interface.
214 *
215 * @param i interface class
216 */
217#define COM_IIDOF(I) _ATL_IIDOF (I)
218
219#else /* defined (RT_OS_WINDOWS) */
220
221#error "VBOX_WITH_XPCOM must be defined on a platform other than Windows!"
222
223#endif /* defined (RT_OS_WINDOWS) */
224
225#else /* !defined (VBOX_WITH_XPCOM) */
226
227// XPCOM
228/////////////////////////////////////////////////////////////////////////////
229
230#if defined (RT_OS_DARWIN) || (defined (QT_VERSION) && (QT_VERSION >= 0x040000))
231 /* CFBase.h defines these &
232 * qglobal.h from Qt4 defines these */
233# undef FALSE
234# undef TRUE
235#endif /* RT_OS_DARWIN || QT_VERSION */
236
237#include <nsID.h>
238
239#define ATL_NO_VTABLE
240#define DECLARE_CLASSFACTORY(a)
241#define DECLARE_CLASSFACTORY_SINGLETON(a)
242#define DECLARE_REGISTRY_RESOURCEID(a)
243#define DECLARE_NOT_AGGREGATABLE(a)
244#define DECLARE_PROTECT_FINAL_CONSTRUCT()
245#define BEGIN_COM_MAP(a)
246#define COM_INTERFACE_ENTRY(a)
247#define COM_INTERFACE_ENTRY2(a,b)
248#define END_COM_MAP() NS_DECL_ISUPPORTS
249
250#define HRESULT nsresult
251#define SUCCEEDED NS_SUCCEEDED
252#define FAILED NS_FAILED
253
254#define SUCCEEDED_WARNING(rc) (NS_SUCCEEDED (rc) && (rc) != NS_OK)
255
256#define FAILED_DEAD_INTERFACE(rc) (false) /**< @todo */
257
258#define IUnknown nsISupports
259
260#define BOOL PRBool
261#define BYTE PRUint8
262#define SHORT PRInt16
263#define USHORT PRUint16
264#define LONG PRInt32
265#define ULONG PRUint32
266#define LONG64 PRInt64
267#define ULONG64 PRUint64
268/* XPCOM has only 64bit floats */
269#define FLOAT PRFloat64
270#define DOUBLE PRFloat64
271
272#define FALSE PR_FALSE
273#define TRUE PR_TRUE
274
275#define OLECHAR wchar_t
276
277/* note: typedef to semantically match BSTR on Win32 */
278typedef PRUnichar *BSTR;
279typedef const PRUnichar *CBSTR;
280typedef BSTR *LPBSTR;
281
282/** Input BSTR argument the interface method declaration. */
283#define IN_BSTR CBSTR
284
285/**
286 * Type to define a raw GUID variable (for members use the com::Guid class
287 * instead).
288 */
289#define GUID nsID
290/** Input GUID argument the interface method declaration. */
291#define IN_GUID const nsID &
292/** Output GUID argument the interface method declaration. */
293#define OUT_GUID nsID **
294
295/** Makes the name of the getter interface function (n must be capitalized). */
296#define COMGETTER(n) Get##n
297/** Makes the name of the setter interface function (n must be capitalized). */
298#define COMSETTER(n) Set##n
299
300/* safearray input parameter macros */
301#define ComSafeArrayIn(aType, aArg) PRUint32 aArg##Size, aType *aArg
302#define ComSafeArrayInIsNull(aArg) ((aArg) == NULL)
303#define ComSafeArrayInArg(aArg) aArg##Size, aArg
304
305/* safearray output parameter macros */
306#define ComSafeArrayOut(aType, aArg) PRUint32 *aArg##Size, aType **aArg
307#define ComSafeArrayOutIsNull(aArg) ((aArg) == NULL)
308#define ComSafeArrayOutArg(aArg) aArg##Size, aArg
309
310/* safearray input parameter macros for GUID */
311#define ComSafeGUIDArrayIn(aArg) PRUint32 aArg##Size, const nsID **aArg
312#define ComSafeGUIDArrayInIsNull(aArg) ComSafeArrayInIsNull (aArg)
313#define ComSafeGUIDArrayInArg(aArg) ComSafeArrayInArg (aArg)
314
315/* safearray output parameter macros for GUID */
316#define ComSafeGUIDArrayOut(aArg) PRUint32 *aArg##Size, nsID ***aArg
317#define ComSafeGUIDArrayOutIsNull(aArg) ComSafeArrayOutIsNull (aArg)
318#define ComSafeGUIDArrayOutArg(aArg) ComSafeArrayOutArg (aArg)
319
320/* CLSID and IID for compatibility with Win32 */
321typedef nsCID CLSID;
322typedef nsIID IID;
323
324/* OLE error codes */
325#define S_OK ((nsresult) NS_OK)
326#define E_UNEXPECTED NS_ERROR_UNEXPECTED
327#define E_NOTIMPL NS_ERROR_NOT_IMPLEMENTED
328#define E_OUTOFMEMORY NS_ERROR_OUT_OF_MEMORY
329#define E_INVALIDARG NS_ERROR_INVALID_ARG
330#define E_NOINTERFACE NS_ERROR_NO_INTERFACE
331#define E_POINTER NS_ERROR_NULL_POINTER
332#define E_ABORT NS_ERROR_ABORT
333#define E_FAIL NS_ERROR_FAILURE
334/* Note: a better analog for E_ACCESSDENIED would probably be
335 * NS_ERROR_NOT_AVAILABLE, but we want binary compatibility for now. */
336#define E_ACCESSDENIED ((nsresult) 0x80070005L)
337
338#define STDMETHOD(a) NS_IMETHOD a
339#define STDMETHODIMP NS_IMETHODIMP
340
341#define COM_IIDOF(I) NS_GET_IID (I)
342
343/* A few very simple ATL emulator classes to provide
344 * FinalConstruct()/FinalRelease() functionality on Linux. */
345
346class CComMultiThreadModel
347{
348};
349
350template <class Base> class CComObjectRootEx : public Base
351{
352public:
353 HRESULT FinalConstruct() { return S_OK; }
354 void FinalRelease() {}
355};
356
357template <class Base> class CComObject : public Base
358{
359public:
360 virtual ~CComObject() { this->FinalRelease(); }
361};
362
363/* helper functions */
364extern "C"
365{
366BSTR SysAllocString (const OLECHAR* sz);
367BSTR SysAllocStringByteLen (char *psz, unsigned int len);
368BSTR SysAllocStringLen (const OLECHAR *pch, unsigned int cch);
369void SysFreeString (BSTR bstr);
370int SysReAllocString (BSTR *pbstr, const OLECHAR *psz);
371int SysReAllocStringLen (BSTR *pbstr, const OLECHAR *psz, unsigned int cch);
372unsigned int SysStringByteLen (BSTR bstr);
373unsigned int SysStringLen (BSTR bstr);
374}
375
376/**
377 * 'Constructor' for the component class.
378 * This constructor, as opposed to NS_GENERIC_FACTORY_CONSTRUCTOR,
379 * assumes that the component class is derived from the CComObjectRootEx<>
380 * template, so it calls FinalConstruct() right after object creation
381 * and ensures that FinalRelease() will be called right before destruction.
382 * The result from FinalConstruct() is returned to the caller.
383 */
384#define NS_GENERIC_FACTORY_CONSTRUCTOR_WITH_RC(_InstanceClass) \
385static NS_IMETHODIMP \
386_InstanceClass##Constructor(nsISupports *aOuter, REFNSIID aIID, \
387 void **aResult) \
388{ \
389 nsresult rv; \
390 \
391 *aResult = NULL; \
392 if (NULL != aOuter) { \
393 rv = NS_ERROR_NO_AGGREGATION; \
394 return rv; \
395 } \
396 \
397 CComObject <_InstanceClass> *inst = new CComObject <_InstanceClass>(); \
398 if (NULL == inst) { \
399 rv = NS_ERROR_OUT_OF_MEMORY; \
400 return rv; \
401 } \
402 \
403 NS_ADDREF(inst); /* protect FinalConstruct() */ \
404 rv = inst->FinalConstruct(); \
405 if (NS_SUCCEEDED(rv)) \
406 rv = inst->QueryInterface(aIID, aResult); \
407 NS_RELEASE(inst); \
408 \
409 return rv; \
410}
411
412/**
413 * 'Constructor' that uses an existing getter function that gets a singleton.
414 * The getter function must have the following prototype:
415 * nsresult _GetterProc (_InstanceClass **inst)
416 * This constructor, as opposed to NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR,
417 * lets the getter function return a result code that is passed back to the
418 * caller that tries to instantiate the object.
419 * NOTE: assumes that getter does an AddRef - so additional AddRef is not done.
420 */
421#define NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR_WITH_RC(_InstanceClass, _GetterProc) \
422static NS_IMETHODIMP \
423_InstanceClass##Constructor(nsISupports *aOuter, REFNSIID aIID, \
424 void **aResult) \
425{ \
426 nsresult rv; \
427 \
428 _InstanceClass * inst = NULL; /* initialized to shut up gcc */ \
429 \
430 *aResult = NULL; \
431 if (NULL != aOuter) { \
432 rv = NS_ERROR_NO_AGGREGATION; \
433 return rv; \
434 } \
435 \
436 rv = _GetterProc(&inst); \
437 if (NS_FAILED(rv)) \
438 return rv; \
439 \
440 /* sanity check */ \
441 if (NULL == inst) \
442 return NS_ERROR_OUT_OF_MEMORY; \
443 \
444 /* NS_ADDREF(inst); */ \
445 if (NS_SUCCEEDED(rv)) { \
446 rv = inst->QueryInterface(aIID, aResult); \
447 } \
448 NS_RELEASE(inst); \
449 \
450 return rv; \
451}
452
453#endif /* !defined (VBOX_WITH_XPCOM) */
454
455/**
456 * Declares a wchar_t string literal from the argument.
457 * Necessary to overcome MSC / GCC differences.
458 * @param s expression to stringify
459 */
460#if defined (_MSC_VER)
461# define WSTR_LITERAL(s) L#s
462#elif defined (__GNUC__)
463# define WSTR_LITERAL(s) L""#s
464#else
465# error "Unsupported compiler!"
466#endif
467
468namespace com
469{
470
471/**
472 * "First worst" result type.
473 *
474 * Variables of this class are used instead of HRESULT variables when it is
475 * desirable to memorize the "first worst" result code instead of the last
476 * assigned one. In other words, an assignment operation to a variable of this
477 * class will succeed only if the result code to assign has worse severity. The
478 * following table demonstrate this (the first column lists the previous result
479 * code stored in the variable, the first row lists the new result code being
480 * assigned, 'A' means the assignment will take place, '> S_OK' means a warning
481 * result code):
482 *
483 * {{{
484 * FAILED > S_OK S_OK
485 * FAILED - - -
486 * > S_OK A - -
487 * S_OK A A -
488 *
489 * }}}
490 *
491 * In practice, you will need to use a FWResult variable when you call some COM
492 * method B after another COM method A fails and want to return the result code
493 * of A even if B also fails, but want to return the failed result code of B if
494 * A issues a warning or succeeds.
495 */
496class FWResult
497{
498
499public:
500
501 /**
502 * Constructs a new variable. Note that by default this constructor sets the
503 * result code to E_FAIL to make sure a failure is returned to the caller if
504 * the variable is never assigned another value (which is considered as the
505 * improper use of this class).
506 */
507 FWResult (HRESULT aRC = E_FAIL) : mRC (aRC) {}
508
509 FWResult &operator= (HRESULT aRC)
510 {
511 if ((FAILED (aRC) && !FAILED (mRC)) ||
512 (mRC == S_OK && aRC != S_OK))
513 mRC = aRC;
514
515 return *this;
516 }
517
518 operator HRESULT() const { return mRC; }
519
520 HRESULT *operator&() { return &mRC; }
521
522private:
523
524 HRESULT mRC;
525};
526
527/**
528 * "Last worst" result type.
529 *
530 * Variables of this class are used instead of HRESULT variables when it is
531 * desirable to memorize the "last worst" result code instead of the last
532 * assigned one. In other words, an assignment operation to a variable of this
533 * class will succeed only if the result code to assign has the same or worse
534 * severity. The following table demonstrate this (the first column lists the
535 * previous result code stored in the variable, the first row lists the new
536 * assigned, 'A' means the assignment will take place, '> S_OK' means a warning
537 * result code):
538 *
539 * {{{
540 * FAILED > S_OK S_OK
541 * FAILED A - -
542 * > S_OK A A -
543 * S_OK A A -
544 *
545 * }}}
546 *
547 * In practice, you will need to use a LWResult variable when you call some COM
548 * method B after COM method A fails and want to return the result code of B
549 * if B also fails, but still want to return the failed result code of A if B
550 * issues a warning or succeeds.
551 */
552class LWResult
553{
554
555public:
556
557 /**
558 * Constructs a new variable. Note that by default this constructor sets the
559 * result code to E_FAIL to make sure a failure is returned to the caller if
560 * the variable is never assigned another value (which is considered as the
561 * improper use of this class).
562 */
563 LWResult (HRESULT aRC = E_FAIL) : mRC (aRC) {}
564
565 LWResult &operator= (HRESULT aRC)
566 {
567 if (FAILED (aRC) ||
568 (SUCCEEDED (mRC) && aRC != S_OK))
569 mRC = aRC;
570
571 return *this;
572 }
573
574 operator HRESULT() const { return mRC; }
575
576 HRESULT *operator&() { return &mRC; }
577
578private:
579
580 HRESULT mRC;
581};
582
583// use this macro to implement scriptable interfaces
584#ifdef RT_OS_WINDOWS
585#define VBOX_SCRIPTABLE_IMPL(iface) \
586 public IDispatchImpl<iface, &IID_##iface, &LIBID_VirtualBox, \
587 kTypeLibraryMajorVersion, kTypeLibraryMinorVersion>
588
589#define VBOX_SCRIPTABLE_DISPATCH_IMPL(iface) \
590 STDMETHOD(QueryInterface)(REFIID riid , void **ppObj) \
591 { \
592 if (riid == IID_IUnknown) \
593 { \
594 *ppObj = (IUnknown*)this; \
595 AddRef(); \
596 return S_OK; \
597 } \
598 if (riid == IID_IDispatch) \
599 { \
600 *ppObj = (IDispatch*)this; \
601 AddRef(); \
602 return S_OK; \
603 } \
604 if (riid == IID_##iface) \
605 { \
606 *ppObj = (iface*)this; \
607 AddRef(); \
608 return S_OK; \
609 } \
610 *ppObj = NULL; \
611 return E_NOINTERFACE; \
612 }
613#else
614#define VBOX_SCRIPTABLE_IMPL(iface) \
615 public iface
616#define VBOX_SCRIPTABLE_DISPATCH_IMPL(iface)
617#endif
618
619
620} /* namespace com */
621
622#endif /* ___VBox_com_defs_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