VirtualBox

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

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

Main/glue: prepare for the day we have float/double parameters in the API

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 22.9 KB
Line 
1/** @file
2 * MS COM / XPCOM Abstraction Layer:
3 * Common definitions
4 */
5
6/*
7 * Copyright (C) 2006-2010 Sun Microsystems, Inc.
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.215389.xyz. 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 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
27 * Clara, CA 95054 USA or visit http://www.sun.com if you need
28 * additional information or have any questions.
29 */
30
31#ifndef ___VBox_com_defs_h
32#define ___VBox_com_defs_h
33
34/* Make sure all the stdint.h macros are included - must come first! */
35#ifndef __STDC_LIMIT_MACROS
36# define __STDC_LIMIT_MACROS
37#endif
38#ifndef __STDC_CONSTANT_MACROS
39# define __STDC_CONSTANT_MACROS
40#endif
41
42#if defined (RT_OS_OS2)
43
44#if defined(RT_MAX) && RT_MAX != 22
45# error RT_MAX already defined by <iprt/cdefs.h>! Make sure <VBox/com/defs.h> \
46 is included before it.
47#endif
48
49/* Make sure OS/2 Toolkit headers are pulled in to have BOOL/ULONG/etc. typedefs
50 * already defined in order to be able to redefine them using #define. It's
51 * also important to do it before iprt/cdefs.h, otherwise we'll lose RT_MAX in
52 * all code that uses COM Glue. */
53#define INCL_BASE
54#define INCL_PM
55#include <os2.h>
56
57/* OS/2 Toolkit defines TRUE and FALSE */
58#undef FALSE
59#undef TRUE
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#if !defined (VBOX_WITH_XPCOM)
69
70#if defined (RT_OS_WINDOWS)
71
72// Windows COM
73/////////////////////////////////////////////////////////////////////////////
74
75#include <objbase.h>
76#ifndef VBOX_COM_NO_ATL
77# include <atlbase.h>
78#include <atlcom.h>
79#endif
80
81#define NS_DECL_ISUPPORTS
82#define NS_IMPL_ISUPPORTS1_CI(a, b)
83
84/* these are XPCOM only, one for every interface implemented */
85#define NS_DECL_ISUPPORTS
86
87/** Returns @c true if @a rc represents a warning result code */
88#define SUCCEEDED_WARNING(rc) (SUCCEEDED (rc) && (rc) != S_OK)
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 IUnknown nsISupports
257
258#define BOOL PRBool
259#define BYTE PRUint8
260#define SHORT PRInt16
261#define USHORT PRUint16
262#define LONG PRInt32
263#define ULONG PRUint32
264#define LONG64 PRInt64
265#define ULONG64 PRUint64
266/* XPCOM has only 64bit floats */
267#define FLOAT PRFloat64
268#define DOUBLE PRFloat64
269#define
270
271#define FALSE PR_FALSE
272#define TRUE PR_TRUE
273
274#define OLECHAR wchar_t
275
276/* note: typedef to semantically match BSTR on Win32 */
277typedef PRUnichar *BSTR;
278typedef const PRUnichar *CBSTR;
279typedef BSTR *LPBSTR;
280
281/** Input BSTR argument the interface method declaration. */
282#define IN_BSTR CBSTR
283
284/**
285 * Type to define a raw GUID variable (for members use the com::Guid class
286 * instead).
287 */
288#define GUID nsID
289/** Input GUID argument the interface method declaration. */
290#define IN_GUID const nsID &
291/** Output GUID argument the interface method declaration. */
292#define OUT_GUID nsID **
293
294/** Makes the name of the getter interface function (n must be capitalized). */
295#define COMGETTER(n) Get##n
296/** Makes the name of the setter interface function (n must be capitalized). */
297#define COMSETTER(n) Set##n
298
299/* safearray input parameter macros */
300#define ComSafeArrayIn(aType, aArg) PRUint32 aArg##Size, aType *aArg
301#define ComSafeArrayInIsNull(aArg) ((aArg) == NULL)
302#define ComSafeArrayInArg(aArg) aArg##Size, aArg
303
304/* safearray output parameter macros */
305#define ComSafeArrayOut(aType, aArg) PRUint32 *aArg##Size, aType **aArg
306#define ComSafeArrayOutIsNull(aArg) ((aArg) == NULL)
307#define ComSafeArrayOutArg(aArg) aArg##Size, aArg
308
309/* safearray input parameter macros for GUID */
310#define ComSafeGUIDArrayIn(aArg) PRUint32 aArg##Size, const nsID **aArg
311#define ComSafeGUIDArrayInIsNull(aArg) ComSafeArrayInIsNull (aArg)
312#define ComSafeGUIDArrayInArg(aArg) ComSafeArrayInArg (aArg)
313
314/* safearray output parameter macros for GUID */
315#define ComSafeGUIDArrayOut(aArg) PRUint32 *aArg##Size, nsID ***aArg
316#define ComSafeGUIDArrayOutIsNull(aArg) ComSafeArrayOutIsNull (aArg)
317#define ComSafeGUIDArrayOutArg(aArg) ComSafeArrayOutArg (aArg)
318
319/* CLSID and IID for compatibility with Win32 */
320typedef nsCID CLSID;
321typedef nsIID IID;
322
323/* OLE error codes */
324#define S_OK ((nsresult) NS_OK)
325#define E_UNEXPECTED NS_ERROR_UNEXPECTED
326#define E_NOTIMPL NS_ERROR_NOT_IMPLEMENTED
327#define E_OUTOFMEMORY NS_ERROR_OUT_OF_MEMORY
328#define E_INVALIDARG NS_ERROR_INVALID_ARG
329#define E_NOINTERFACE NS_ERROR_NO_INTERFACE
330#define E_POINTER NS_ERROR_NULL_POINTER
331#define E_ABORT NS_ERROR_ABORT
332#define E_FAIL NS_ERROR_FAILURE
333/* Note: a better analog for E_ACCESSDENIED would probably be
334 * NS_ERROR_NOT_AVAILABLE, but we want binary compatibility for now. */
335#define E_ACCESSDENIED ((nsresult) 0x80070005L)
336
337#define STDMETHOD(a) NS_IMETHOD a
338#define STDMETHODIMP NS_IMETHODIMP
339
340#define COM_IIDOF(I) NS_GET_IID (I)
341
342/* A few very simple ATL emulator classes to provide
343 * FinalConstruct()/FinalRelease() functionality on Linux. */
344
345class CComMultiThreadModel
346{
347};
348
349template <class Base> class CComObjectRootEx : public Base
350{
351public:
352 HRESULT FinalConstruct() { return S_OK; }
353 void FinalRelease() {}
354};
355
356template <class Base> class CComObject : public Base
357{
358public:
359 virtual ~CComObject() { this->FinalRelease(); }
360};
361
362/* helper functions */
363extern "C"
364{
365BSTR SysAllocString (const OLECHAR* sz);
366BSTR SysAllocStringByteLen (char *psz, unsigned int len);
367BSTR SysAllocStringLen (const OLECHAR *pch, unsigned int cch);
368void SysFreeString (BSTR bstr);
369int SysReAllocString (BSTR *pbstr, const OLECHAR *psz);
370int SysReAllocStringLen (BSTR *pbstr, const OLECHAR *psz, unsigned int cch);
371unsigned int SysStringByteLen (BSTR bstr);
372unsigned int SysStringLen (BSTR bstr);
373}
374
375/**
376 * 'Constructor' for the component class.
377 * This constructor, as opposed to NS_GENERIC_FACTORY_CONSTRUCTOR,
378 * assumes that the component class is derived from the CComObjectRootEx<>
379 * template, so it calls FinalConstruct() right after object creation
380 * and ensures that FinalRelease() will be called right before destruction.
381 * The result from FinalConstruct() is returned to the caller.
382 */
383#define NS_GENERIC_FACTORY_CONSTRUCTOR_WITH_RC(_InstanceClass) \
384static NS_IMETHODIMP \
385_InstanceClass##Constructor(nsISupports *aOuter, REFNSIID aIID, \
386 void **aResult) \
387{ \
388 nsresult rv; \
389 \
390 *aResult = NULL; \
391 if (NULL != aOuter) { \
392 rv = NS_ERROR_NO_AGGREGATION; \
393 return rv; \
394 } \
395 \
396 CComObject <_InstanceClass> *inst = new CComObject <_InstanceClass>(); \
397 if (NULL == inst) { \
398 rv = NS_ERROR_OUT_OF_MEMORY; \
399 return rv; \
400 } \
401 \
402 NS_ADDREF(inst); /* protect FinalConstruct() */ \
403 rv = inst->FinalConstruct(); \
404 if (NS_SUCCEEDED(rv)) \
405 rv = inst->QueryInterface(aIID, aResult); \
406 NS_RELEASE(inst); \
407 \
408 return rv; \
409}
410
411/**
412 * 'Constructor' that uses an existing getter function that gets a singleton.
413 * The getter function must have the following prototype:
414 * nsresult _GetterProc (_InstanceClass **inst)
415 * This constructor, as opposed to NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR,
416 * lets the getter function return a result code that is passed back to the
417 * caller that tries to instantiate the object.
418 * NOTE: assumes that getter does an AddRef - so additional AddRef is not done.
419 */
420#define NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR_WITH_RC(_InstanceClass, _GetterProc) \
421static NS_IMETHODIMP \
422_InstanceClass##Constructor(nsISupports *aOuter, REFNSIID aIID, \
423 void **aResult) \
424{ \
425 nsresult rv; \
426 \
427 _InstanceClass * inst = NULL; /* initialized to shut up gcc */ \
428 \
429 *aResult = NULL; \
430 if (NULL != aOuter) { \
431 rv = NS_ERROR_NO_AGGREGATION; \
432 return rv; \
433 } \
434 \
435 rv = _GetterProc(&inst); \
436 if (NS_FAILED(rv)) \
437 return rv; \
438 \
439 /* sanity check */ \
440 if (NULL == inst) \
441 return NS_ERROR_OUT_OF_MEMORY; \
442 \
443 /* NS_ADDREF(inst); */ \
444 if (NS_SUCCEEDED(rv)) { \
445 rv = inst->QueryInterface(aIID, aResult); \
446 } \
447 NS_RELEASE(inst); \
448 \
449 return rv; \
450}
451
452#endif /* !defined (VBOX_WITH_XPCOM) */
453
454/**
455 * Declares a wchar_t string literal from the argument.
456 * Necessary to overcome MSC / GCC differences.
457 * @param s expression to stringify
458 */
459#if defined (_MSC_VER)
460# define WSTR_LITERAL(s) L#s
461#elif defined (__GNUC__)
462# define WSTR_LITERAL(s) L""#s
463#else
464# error "Unsupported compiler!"
465#endif
466
467namespace com
468{
469
470/**
471 * "First worst" result type.
472 *
473 * Variables of this class are used instead of HRESULT variables when it is
474 * desirable to memorize the "first worst" result code instead of the last
475 * assigned one. In other words, an assignment operation to a variable of this
476 * class will succeed only if the result code to assign has worse severity. The
477 * following table demonstrate this (the first column lists the previous result
478 * code stored in the variable, the first row lists the new result code being
479 * assigned, 'A' means the assignment will take place, '> S_OK' means a warning
480 * result code):
481 *
482 * {{{
483 * FAILED > S_OK S_OK
484 * FAILED - - -
485 * > S_OK A - -
486 * S_OK A A -
487 *
488 * }}}
489 *
490 * In practice, you will need to use a FWResult variable when you call some COM
491 * method B after another COM method A fails and want to return the result code
492 * of A even if B also fails, but want to return the failed result code of B if
493 * A issues a warning or succeeds.
494 */
495class FWResult
496{
497
498public:
499
500 /**
501 * Constructs a new variable. Note that by default this constructor sets the
502 * result code to E_FAIL to make sure a failure is returned to the caller if
503 * the variable is never assigned another value (which is considered as the
504 * improper use of this class).
505 */
506 FWResult (HRESULT aRC = E_FAIL) : mRC (aRC) {}
507
508 FWResult &operator= (HRESULT aRC)
509 {
510 if ((FAILED (aRC) && !FAILED (mRC)) ||
511 (mRC == S_OK && aRC != S_OK))
512 mRC = aRC;
513
514 return *this;
515 }
516
517 operator HRESULT() const { return mRC; }
518
519 HRESULT *operator&() { return &mRC; }
520
521private:
522
523 HRESULT mRC;
524};
525
526/**
527 * "Last worst" result type.
528 *
529 * Variables of this class are used instead of HRESULT variables when it is
530 * desirable to memorize the "last worst" result code instead of the last
531 * assigned one. In other words, an assignment operation to a variable of this
532 * class will succeed only if the result code to assign has the same or worse
533 * severity. The following table demonstrate this (the first column lists the
534 * previous result code stored in the variable, the first row lists the new
535 * assigned, 'A' means the assignment will take place, '> S_OK' means a warning
536 * result code):
537 *
538 * {{{
539 * FAILED > S_OK S_OK
540 * FAILED A - -
541 * > S_OK A A -
542 * S_OK A A -
543 *
544 * }}}
545 *
546 * In practice, you will need to use a LWResult variable when you call some COM
547 * method B after COM method A fails and want to return the result code of B
548 * if B also fails, but still want to return the failed result code of A if B
549 * issues a warning or succeeds.
550 */
551class LWResult
552{
553
554public:
555
556 /**
557 * Constructs a new variable. Note that by default this constructor sets the
558 * result code to E_FAIL to make sure a failure is returned to the caller if
559 * the variable is never assigned another value (which is considered as the
560 * improper use of this class).
561 */
562 LWResult (HRESULT aRC = E_FAIL) : mRC (aRC) {}
563
564 LWResult &operator= (HRESULT aRC)
565 {
566 if (FAILED (aRC) ||
567 (SUCCEEDED (mRC) && aRC != S_OK))
568 mRC = aRC;
569
570 return *this;
571 }
572
573 operator HRESULT() const { return mRC; }
574
575 HRESULT *operator&() { return &mRC; }
576
577private:
578
579 HRESULT mRC;
580};
581
582// use this macro to implement scriptable interfaces
583#ifdef RT_OS_WINDOWS
584#define VBOX_SCRIPTABLE_IMPL(iface) \
585 public IDispatchImpl<iface, &IID_##iface, &LIBID_VirtualBox, \
586 kTypeLibraryMajorVersion, kTypeLibraryMinorVersion>
587
588#define VBOX_SCRIPTABLE_DISPATCH_IMPL(iface) \
589 STDMETHOD(QueryInterface)(REFIID riid , void **ppObj) \
590 { \
591 if (riid == IID_IUnknown) \
592 { \
593 *ppObj = (IUnknown*)this; \
594 AddRef(); \
595 return S_OK; \
596 } \
597 if (riid == IID_IDispatch) \
598 { \
599 *ppObj = (IDispatch*)this; \
600 AddRef(); \
601 return S_OK; \
602 } \
603 if (riid == IID_##iface) \
604 { \
605 *ppObj = (iface*)this; \
606 AddRef(); \
607 return S_OK; \
608 } \
609 *ppObj = NULL; \
610 return E_NOINTERFACE; \
611 }
612#else
613#define VBOX_SCRIPTABLE_IMPL(iface) \
614 public iface
615#define VBOX_SCRIPTABLE_DISPATCH_IMPL(iface)
616#endif
617
618
619} /* namespace com */
620
621#endif /* ___VBox_com_defs_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