VirtualBox

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

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

Main: make VBox interfaces scriptable (that is, callable from Python and VisualBasic)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 21.0 KB
Line 
1/** @file
2 * MS COM / XPCOM Abstraction Layer:
3 * Common definitions
4 */
5
6/*
7 * Copyright (C) 2006-2009 Sun Microsystems, Inc.
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 * 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#define NS_DECL_IVIRTUALBOX
87#define NS_DECL_IMACHINECOLLECTION
88#define NS_DECL_IMACHINE
89
90/** Returns @c true if @a rc represents a warning result code */
91#define SUCCEEDED_WARNING(rc) (SUCCEEDED (rc) && (rc) != S_OK)
92
93/** Immutable BSTR string */
94typedef const OLECHAR *CBSTR;
95
96/** Input BSTR argument of interface method declaration. */
97#define IN_BSTR BSTR
98
99/** Input GUID argument of interface method declaration. */
100#define IN_GUID GUID
101/** Output GUID argument of interface method declaration. */
102#define OUT_GUID GUID*
103
104/** Makes the name of the getter interface function (n must be capitalized). */
105#define COMGETTER(n) get_##n
106/** Makes the name of the setter interface function (n must be capitalized). */
107#define COMSETTER(n) put_##n
108
109/**
110 * Declares an input safearray parameter in the COM method implementation. Also
111 * used to declare the COM attribute setter parameter. Corresponds to either of
112 * the following XIDL definitions:
113 * <pre>
114 * <param name="arg" ... dir="in" safearray="yes"/>
115 * ...
116 * <attribute name="arg" ... safearray="yes"/>
117 * </pre>
118 *
119 * The method implementation should use the com::SafeArray helper class to work
120 * with parameters declared using this define.
121 *
122 * @param aType Array element type.
123 * @param aArg Parameter/attribute name.
124 */
125#define ComSafeArrayIn(aType, aArg) SAFEARRAY **aArg
126
127/**
128 * Expands to @true if the given input safearray parameter is a "null pointer"
129 * which makes it impossible to use it for reading safearray data.
130 */
131#define ComSafeArrayInIsNull(aArg) ((aArg) == NULL || *(aArg) == NULL)
132
133/**
134 * Wraps the given parameter name to generate an expression that is suitable for
135 * passing the parameter to functions that take input safearray parameters
136 * declared using the ComSafeArrayIn marco.
137 *
138 * @param aArg Parameter name to wrap. The given parameter must be declared
139 * within the calling function using the ComSafeArrayIn macro.
140 */
141#define ComSafeArrayInArg(aArg) aArg
142
143/**
144 * Declares an output safearray parameter in the COM method implementation. Also
145 * used to declare the COM attribute getter parameter. Corresponds to either of
146 * the following XIDL definitions:
147 * <pre>
148 * <param name="arg" ... dir="out" safearray="yes"/>
149 * <param name="arg" ... dir="return" safearray="yes"/>
150 * ...
151 * <attribute name="arg" ... safearray="yes"/>
152 * </pre>
153 *
154 * The method implementation should use the com::SafeArray helper class to work
155 * with parameters declared using this define.
156 *
157 * @param aType Array element type.
158 * @param aArg Parameter/attribute name.
159 */
160#define ComSafeArrayOut(aType, aArg) SAFEARRAY **aArg
161
162/**
163 * Expands to @true if the given output safearray parameter is a "null pointer"
164 * which makes it impossible to use it for returning a safearray.
165 */
166#define ComSafeArrayOutIsNull(aArg) ((aArg) == NULL)
167
168/**
169 * Wraps the given parameter name to generate an expression that is suitable for
170 * passing the parameter to functions that take output safearray parameters
171 * declared using the ComSafeArrayOut marco.
172 *
173 * @param aArg Parameter name to wrap. The given parameter must be declared
174 * within the calling function using the ComSafeArrayOut macro.
175 */
176#define ComSafeArrayOutArg(aArg) aArg
177
178/**
179 * Version of ComSafeArrayIn for GUID.
180 * @param aArg Parameter name to wrap.
181 */
182#define ComSafeGUIDArrayIn(aArg) SAFEARRAY **aArg
183
184/**
185 * Version of ComSafeArrayInIsNull for GUID.
186 * @param aArg Parameter name to wrap.
187 */
188#define ComSafeGUIDArrayInIsNull(aArg) ComSafeArrayInIsNull (aArg)
189
190/**
191 * Version of ComSafeArrayInArg for GUID.
192 * @param aArg Parameter name to wrap.
193 */
194#define ComSafeGUIDArrayInArg(aArg) ComSafeArrayInArg (aArg)
195
196/**
197 * Version of ComSafeArrayOut for GUID.
198 * @param aArg Parameter name to wrap.
199 */
200#define ComSafeGUIDArrayOut(aArg) SAFEARRAY **aArg
201
202/**
203 * Version of ComSafeArrayOutIsNull for GUID.
204 * @param aArg Parameter name to wrap.
205 */
206#define ComSafeGUIDArrayOutIsNull(aArg) ComSafeArrayOutIsNull (aArg)
207
208/**
209 * Version of ComSafeArrayOutArg for GUID.
210 * @param aArg Parameter name to wrap.
211 */
212#define ComSafeGUIDArrayOutArg(aArg) ComSafeArrayOutArg (aArg)
213
214/**
215 * Returns the const reference to the IID (i.e., |const GUID &|) of the given
216 * interface.
217 *
218 * @param i interface class
219 */
220#define COM_IIDOF(I) _ATL_IIDOF (I)
221
222#else /* defined (RT_OS_WINDOWS) */
223
224#error "VBOX_WITH_XPCOM must be defined on a platform other than Windows!"
225
226#endif /* defined (RT_OS_WINDOWS) */
227
228#else /* !defined (VBOX_WITH_XPCOM) */
229
230// XPCOM
231/////////////////////////////////////////////////////////////////////////////
232
233#if defined (RT_OS_DARWIN) || (defined (QT_VERSION) && (QT_VERSION >= 0x040000))
234 /* CFBase.h defines these &
235 * qglobal.h from Qt4 defines these */
236# undef FALSE
237# undef TRUE
238#endif /* RT_OS_DARWIN || QT_VERSION */
239
240#include <nsID.h>
241
242#define ATL_NO_VTABLE
243#define DECLARE_CLASSFACTORY(a)
244#define DECLARE_CLASSFACTORY_SINGLETON(a)
245#define DECLARE_REGISTRY_RESOURCEID(a)
246#define DECLARE_NOT_AGGREGATABLE(a)
247#define DECLARE_PROTECT_FINAL_CONSTRUCT(a)
248#define BEGIN_COM_MAP(a)
249#define COM_INTERFACE_ENTRY(a)
250#define COM_INTERFACE_ENTRY2(a,b)
251#define END_COM_MAP(a)
252
253#define HRESULT nsresult
254#define SUCCEEDED NS_SUCCEEDED
255#define FAILED NS_FAILED
256
257#define SUCCEEDED_WARNING(rc) (NS_SUCCEEDED (rc) && (rc) != NS_OK)
258
259#define IUnknown nsISupports
260
261#define BOOL PRBool
262#define BYTE PRUint8
263#define SHORT PRInt16
264#define USHORT PRUint16
265#define LONG PRInt32
266#define ULONG PRUint32
267#define LONG64 PRInt64
268#define ULONG64 PRUint64
269
270#define FALSE PR_FALSE
271#define TRUE PR_TRUE
272
273#define OLECHAR wchar_t
274
275/* note: typedef to semantically match BSTR on Win32 */
276typedef PRUnichar *BSTR;
277typedef const PRUnichar *CBSTR;
278typedef BSTR *LPBSTR;
279
280/** Input BSTR argument the interface method declaration. */
281#define IN_BSTR CBSTR
282
283/**
284 * Type to define a raw GUID variable (for members use the com::Guid class
285 * instead).
286 */
287#define GUID nsID
288/** Input GUID argument the interface method declaration. */
289#define IN_GUID const nsID &
290/** Output GUID argument the interface method declaration. */
291#define OUT_GUID nsID **
292
293/** Makes the name of the getter interface function (n must be capitalized). */
294#define COMGETTER(n) Get##n
295/** Makes the name of the setter interface function (n must be capitalized). */
296#define COMSETTER(n) Set##n
297
298/* safearray input parameter macros */
299#define ComSafeArrayIn(aType, aArg) PRUint32 aArg##Size, aType *aArg
300#define ComSafeArrayInIsNull(aArg) ((aArg) == NULL)
301#define ComSafeArrayInArg(aArg) aArg##Size, aArg
302
303/* safearray output parameter macros */
304#define ComSafeArrayOut(aType, aArg) PRUint32 *aArg##Size, aType **aArg
305#define ComSafeArrayOutIsNull(aArg) ((aArg) == NULL)
306#define ComSafeArrayOutArg(aArg) aArg##Size, aArg
307
308/* safearray input parameter macros for GUID */
309#define ComSafeGUIDArrayIn(aArg) PRUint32 aArg##Size, const nsID **aArg
310#define ComSafeGUIDArrayInIsNull(aArg) ComSafeArrayInIsNull (aArg)
311#define ComSafeGUIDArrayInArg(aArg) ComSafeArrayInArg (aArg)
312
313/* safearray output parameter macros for GUID */
314#define ComSafeGUIDArrayOut(aArg) PRUint32 *aArg##Size, nsID ***aArg
315#define ComSafeGUIDArrayOutIsNull(aArg) ComSafeArrayOutIsNull (aArg)
316#define ComSafeGUIDArrayOutArg(aArg) ComSafeArrayOutArg (aArg)
317
318/* CLSID and IID for compatibility with Win32 */
319typedef nsCID CLSID;
320typedef nsIID IID;
321
322/* OLE error codes */
323#define S_OK ((nsresult) NS_OK)
324#define E_UNEXPECTED NS_ERROR_UNEXPECTED
325#define E_NOTIMPL NS_ERROR_NOT_IMPLEMENTED
326#define E_OUTOFMEMORY NS_ERROR_OUT_OF_MEMORY
327#define E_INVALIDARG NS_ERROR_INVALID_ARG
328#define E_NOINTERFACE NS_ERROR_NO_INTERFACE
329#define E_POINTER NS_ERROR_NULL_POINTER
330#define E_ABORT NS_ERROR_ABORT
331#define E_FAIL NS_ERROR_FAILURE
332/* Note: a better analog for E_ACCESSDENIED would probably be
333 * NS_ERROR_NOT_AVAILABLE, but we want binary compatibility for now. */
334#define E_ACCESSDENIED ((nsresult) 0x80070005L)
335
336#define STDMETHOD(a) NS_IMETHOD a
337#define STDMETHODIMP NS_IMETHODIMP
338
339#define COM_IIDOF(I) NS_GET_IID (I)
340
341/* Two very simple ATL emulator classes to provide
342 * FinalConstruct()/FinalRelease() functionality on Linux. */
343
344class CComObjectRootEx
345{
346public:
347 HRESULT FinalConstruct() { return S_OK; }
348 void FinalRelease() {}
349};
350
351template <class Base> class CComObject : public Base
352{
353public:
354 virtual ~CComObject() { this->FinalRelease(); }
355};
356
357/* helper functions */
358extern "C"
359{
360BSTR SysAllocString (const OLECHAR* sz);
361BSTR SysAllocStringByteLen (char *psz, unsigned int len);
362BSTR SysAllocStringLen (const OLECHAR *pch, unsigned int cch);
363void SysFreeString (BSTR bstr);
364int SysReAllocString (BSTR *pbstr, const OLECHAR *psz);
365int SysReAllocStringLen (BSTR *pbstr, const OLECHAR *psz, unsigned int cch);
366unsigned int SysStringByteLen (BSTR bstr);
367unsigned int SysStringLen (BSTR bstr);
368}
369
370/**
371 * 'Constructor' for the component class.
372 * This constructor, as opposed to NS_GENERIC_FACTORY_CONSTRUCTOR,
373 * assumes that the component class is derived from the CComObjectRootEx<>
374 * template, so it calls FinalConstruct() right after object creation
375 * and ensures that FinalRelease() will be called right before destruction.
376 * The result from FinalConstruct() is returned to the caller.
377 */
378#define NS_GENERIC_FACTORY_CONSTRUCTOR_WITH_RC(_InstanceClass) \
379static NS_IMETHODIMP \
380_InstanceClass##Constructor(nsISupports *aOuter, REFNSIID aIID, \
381 void **aResult) \
382{ \
383 nsresult rv; \
384 \
385 *aResult = NULL; \
386 if (NULL != aOuter) { \
387 rv = NS_ERROR_NO_AGGREGATION; \
388 return rv; \
389 } \
390 \
391 CComObject <_InstanceClass> *inst = new CComObject <_InstanceClass>(); \
392 if (NULL == inst) { \
393 rv = NS_ERROR_OUT_OF_MEMORY; \
394 return rv; \
395 } \
396 \
397 NS_ADDREF(inst); /* protect FinalConstruct() */ \
398 rv = inst->FinalConstruct(); \
399 if (NS_SUCCEEDED(rv)) \
400 rv = inst->QueryInterface(aIID, aResult); \
401 NS_RELEASE(inst); \
402 \
403 return rv; \
404}
405
406/**
407 * 'Constructor' that uses an existing getter function that gets a singleton.
408 * The getter function must have the following prototype:
409 * nsresult _GetterProc (_InstanceClass **inst)
410 * This constructor, as opposed to NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR,
411 * lets the getter function return a result code that is passed back to the
412 * caller that tries to instantiate the object.
413 * NOTE: assumes that getter does an AddRef - so additional AddRef is not done.
414 */
415#define NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR_WITH_RC(_InstanceClass, _GetterProc) \
416static NS_IMETHODIMP \
417_InstanceClass##Constructor(nsISupports *aOuter, REFNSIID aIID, \
418 void **aResult) \
419{ \
420 nsresult rv; \
421 \
422 _InstanceClass * inst; \
423 \
424 *aResult = NULL; \
425 if (NULL != aOuter) { \
426 rv = NS_ERROR_NO_AGGREGATION; \
427 return rv; \
428 } \
429 \
430 rv = _GetterProc(&inst); \
431 if (NS_FAILED(rv)) \
432 return rv; \
433 \
434 /* sanity check */ \
435 if (NULL == inst) \
436 return NS_ERROR_OUT_OF_MEMORY; \
437 \
438 /* NS_ADDREF(inst); */ \
439 if (NS_SUCCEEDED(rv)) { \
440 rv = inst->QueryInterface(aIID, aResult); \
441 } \
442 NS_RELEASE(inst); \
443 \
444 return rv; \
445}
446
447#endif /* !defined (VBOX_WITH_XPCOM) */
448
449/**
450 * Declares a wchar_t string literal from the argument.
451 * Necessary to overcome MSC / GCC differences.
452 * @param s expression to stringify
453 */
454#if defined (_MSC_VER)
455# define WSTR_LITERAL(s) L#s
456#elif defined (__GNUC__)
457# define WSTR_LITERAL(s) L""#s
458#else
459# error "Unsupported compiler!"
460#endif
461
462namespace com
463{
464
465/**
466 * "First worst" result type.
467 *
468 * Variables of this class are used instead of HRESULT variables when it is
469 * desirable to memorize the "first worst" result code instead of the last
470 * assigned one. In other words, an assignment operation to a variable of this
471 * class will succeed only if the result code to assign has worse severity. The
472 * following table demonstrate this (the first column lists the previous result
473 * code stored in the variable, the first row lists the new result code being
474 * assigned, 'A' means the assignment will take place, '> S_OK' means a warning
475 * result code):
476 *
477 * {{{
478 * FAILED > S_OK S_OK
479 * FAILED - - -
480 * > S_OK A - -
481 * S_OK A A -
482 *
483 * }}}
484 *
485 * In practice, you will need to use a FWResult variable when you call some COM
486 * method B after another COM method A fails and want to return the result code
487 * of A even if B also fails, but want to return the failed result code of B if
488 * A issues a warning or succeeds.
489 */
490class FWResult
491{
492
493public:
494
495 /**
496 * Constructs a new variable. Note that by default this constructor sets the
497 * result code to E_FAIL to make sure a failure is returned to the caller if
498 * the variable is never assigned another value (which is considered as the
499 * improper use of this class).
500 */
501 FWResult (HRESULT aRC = E_FAIL) : mRC (aRC) {}
502
503 FWResult &operator= (HRESULT aRC)
504 {
505 if ((FAILED (aRC) && !FAILED (mRC)) ||
506 (mRC == S_OK && aRC != S_OK))
507 mRC = aRC;
508
509 return *this;
510 }
511
512 operator HRESULT() const { return mRC; }
513
514 HRESULT *operator&() { return &mRC; }
515
516private:
517
518 HRESULT mRC;
519};
520
521/**
522 * "Last worst" result type.
523 *
524 * Variables of this class are used instead of HRESULT variables when it is
525 * desirable to memorize the "last worst" result code instead of the last
526 * assigned one. In other words, an assignment operation to a variable of this
527 * class will succeed only if the result code to assign has the same or worse
528 * severity. The following table demonstrate this (the first column lists the
529 * previous result code stored in the variable, the first row lists the new
530 * assigned, 'A' means the assignment will take place, '> S_OK' means a warning
531 * result code):
532 *
533 * {{{
534 * FAILED > S_OK S_OK
535 * FAILED A - -
536 * > S_OK A A -
537 * S_OK A A -
538 *
539 * }}}
540 *
541 * In practice, you will need to use a LWResult variable when you call some COM
542 * method B after COM method A fails and want to return the result code of B
543 * if B also fails, but still want to return the failed result code of A if B
544 * issues a warning or succeeds.
545 */
546class LWResult
547{
548
549public:
550
551 /**
552 * Constructs a new variable. Note that by default this constructor sets the
553 * result code to E_FAIL to make sure a failure is returned to the caller if
554 * the variable is never assigned another value (which is considered as the
555 * improper use of this class).
556 */
557 LWResult (HRESULT aRC = E_FAIL) : mRC (aRC) {}
558
559 LWResult &operator= (HRESULT aRC)
560 {
561 if (FAILED (aRC) ||
562 (SUCCEEDED (mRC) && aRC != S_OK))
563 mRC = aRC;
564
565 return *this;
566 }
567
568 operator HRESULT() const { return mRC; }
569
570 HRESULT *operator&() { return &mRC; }
571
572private:
573
574 HRESULT mRC;
575};
576
577// use this macro to implement scriptable interfaces
578#ifdef RT_OS_WINDOWS
579#define VBOX_SCRIPTABLE_IMPL(iface) \
580 public IDispatchImpl<iface, &IID_##iface, &LIBID_VirtualBox, \
581 kTypeLibraryMajorVersion, kTypeLibraryMinorVersion>
582#else
583#define VBOX_SCRIPTABLE_IMPL(iface) \
584 public iface
585#endif
586
587
588} /* namespace com */
589
590#endif /* ___VBox_com_defs_h */
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use