VirtualBox

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

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

VBox/com/defs.h,VirtualBoxImpl.cpp: Implemented FAILED_DEAD_INTERFACE() for COM.

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