VirtualBox

root/trunk/include/VBox/com/defs.h

Revision 15051, 20.6 kB (checked in by vboxsync, 1 month ago)

Main: Cleaned up the long standing const BSTR = const (OLECHAR *) on WIn32 vs (const PRunichar) * on XPCOM clash. Cleaned up BSTR/GUID macros (IN_BSTR replaces INPTR BSTR, IN_GUID replaces INPTR GUIDPARAM, OUT_GUID replaces GUIDPARAMOUT).

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1 /** @file
2  * MS COM / XPCOM Abstraction Layer:
3  * Common definitions
4  */
5
6 /*
7  * Copyright (C) 2006-2007 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  * get 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 */
94 typedef const OLECHAR *CBSTR;
95
96 /** Input BSTR argument the interface method declaration. */
97 #define IN_BSTR BSTR
98
99 /** Input GUID argument the interface method declaration. */
100 #define IN_GUID GUID
101 /** Output GUID argument the 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 */
276 typedef PRUnichar *BSTR;
277 typedef const PRUnichar *CBSTR;
278 typedef 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 */
319 typedef nsCID   CLSID;
320 typedef 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
344 class CComObjectRootEx
345 {
346 public:
347     HRESULT FinalConstruct() { return S_OK; }
348     void FinalRelease() {}
349 };
350
351 template <class Base> class CComObject : public Base
352 {
353 public:
354     virtual ~CComObject() { this->FinalRelease(); }
355 };
356
357 /* helper functions */
358 extern "C"
359 {
360 BSTR SysAllocString (const OLECHAR* sz);
361 BSTR SysAllocStringByteLen (char *psz, unsigned int len);
362 BSTR SysAllocStringLen (const OLECHAR *pch, unsigned int cch);
363 void SysFreeString (BSTR bstr);
364 int SysReAllocString (BSTR *pbstr, const OLECHAR *psz);
365 int SysReAllocStringLen (BSTR *pbstr, const OLECHAR *psz, unsigned int cch);
366 unsigned int SysStringByteLen (BSTR bstr);
367 unsigned 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)                \
379 static 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) \
416 static 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 whar_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
462 namespace 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  * On 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  */
490 class FWResult
491 {
492
493 public:
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
516 private:
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  * On 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  */
546 class LWResult
547 {
548
549 public:
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
572 private:
573
574     HRESULT mRC;
575 };
576
577 } /* namespace com */
578
579 #endif /* ___VBox_com_defs_h */
580
Note: See TracBrowser for help on using the browser.

© 2008 Sun Microsystems, Inc.
ContactPrivacy policy