VirtualBox

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

Last change on this file since 60765 was 60765, checked in by vboxsync, 9 years ago

API: stop using ATL and use a vastly smaller lookalike instead, plus a lot of cleanups

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