VirtualBox

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

Last change on this file since 97964 was 96407, checked in by vboxsync, 2 years ago

scm copyright and license note update

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