2017-04-26 11:19:40 +02:00
|
|
|
/**
|
|
|
|
* VirtualBox COM base class definition adjusted to Genode
|
|
|
|
* - based on VBox/Main/include/VirtualBoxBase.h
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Copyright (C) 2006-2013 Oracle Corporation
|
|
|
|
* Copyright (C) 2013-2017 Genode Labs GmbH
|
|
|
|
*
|
|
|
|
* This file is part of VirtualBox Open Source Edition (OSE), as
|
|
|
|
* available from http://www.virtualbox.org. This file is free software;
|
|
|
|
* you can redistribute it and/or modify it under the terms of the GNU
|
|
|
|
* General Public License (GPL) as published by the Free Software
|
|
|
|
* Foundation, in version 2 as it comes in the "COPYING" file of the
|
|
|
|
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
|
|
|
|
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
2014-09-23 13:01:47 +02:00
|
|
|
#ifndef ____H_VIRTUALBOXBASEIMPL
|
|
|
|
#define ____H_VIRTUALBOXBASEIMPL
|
|
|
|
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 19:07:09 +02:00
|
|
|
#include <base/log.h>
|
2014-09-23 13:01:47 +02:00
|
|
|
|
2015-05-04 11:36:45 +02:00
|
|
|
#include <iprt/cdefs.h>
|
2014-09-23 13:01:47 +02:00
|
|
|
#include <iprt/thread.h>
|
|
|
|
|
|
|
|
#include <list>
|
|
|
|
#include <map>
|
|
|
|
|
|
|
|
#include "VBox/com/AutoLock.h"
|
2015-05-04 11:36:45 +02:00
|
|
|
#include "VBox/com/string.h"
|
|
|
|
#include "VBox/com/Guid.h"
|
2014-09-23 13:01:47 +02:00
|
|
|
|
2015-05-04 11:36:45 +02:00
|
|
|
#include "VBox/com/VirtualBox.h"
|
2014-09-23 13:01:47 +02:00
|
|
|
|
|
|
|
namespace com
|
|
|
|
{
|
|
|
|
class ErrorInfo;
|
|
|
|
}
|
|
|
|
|
|
|
|
using namespace com;
|
|
|
|
using namespace util;
|
|
|
|
|
2015-05-04 11:36:45 +02:00
|
|
|
class AutoInitSpan;
|
|
|
|
class AutoUninitSpan;
|
|
|
|
|
|
|
|
class VirtualBox;
|
|
|
|
class Machine;
|
2014-09-23 13:01:47 +02:00
|
|
|
class Medium;
|
|
|
|
|
|
|
|
typedef std::list<ComObjPtr<Medium> > MediaList;
|
|
|
|
typedef std::list<Utf8Str> StringsList;
|
|
|
|
|
2015-05-04 11:36:45 +02:00
|
|
|
class VirtualBoxTranslatable : public util::Lockable
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
|
|
|
|
/* should be used for translations */
|
|
|
|
inline static const char *tr(const char *pcszSourceText,
|
|
|
|
const char *aComment = NULL)
|
|
|
|
{
|
|
|
|
return pcszSourceText;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
class VirtualBoxBase : public VirtualBoxTranslatable
|
|
|
|
{
|
2014-09-23 13:01:47 +02:00
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
enum State { NotReady, Ready, InInit, InUninit, InitFailed, Limited };
|
|
|
|
|
|
|
|
virtual void uninit() { }
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
|
|
|
RWLockHandle *_lock;
|
|
|
|
|
|
|
|
|
|
|
|
void setState(State aState)
|
|
|
|
{
|
|
|
|
Assert(mState != aState);
|
|
|
|
mState = aState;
|
|
|
|
mStateChangeThread = RTThreadSelf();
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Primary state of this object */
|
|
|
|
State mState;
|
|
|
|
/** Thread that caused the last state change */
|
|
|
|
RTTHREAD mStateChangeThread;
|
|
|
|
/** Total number of active calls to this object */
|
|
|
|
unsigned mCallers;
|
|
|
|
/** Posted when the number of callers drops to zero */
|
|
|
|
RTSEMEVENT mZeroCallersSem;
|
|
|
|
/** Posted when the object goes from InInit/InUninit to some other state */
|
|
|
|
RTSEMEVENTMULTI mInitUninitSem;
|
|
|
|
/** Number of threads waiting for mInitUninitDoneSem */
|
|
|
|
unsigned mInitUninitWaiters;
|
|
|
|
|
|
|
|
/** Protects access to state related data members */
|
|
|
|
WriteLockHandle mStateLock;
|
|
|
|
|
|
|
|
/** User-level object lock for subclasses */
|
|
|
|
mutable RWLockHandle *mObjectLock;
|
|
|
|
|
|
|
|
friend class AutoInitSpan;
|
|
|
|
friend class AutoReinitSpan;
|
|
|
|
friend class AutoUninitSpan;
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
|
|
|
HRESULT BaseFinalConstruct() { return S_OK; }
|
|
|
|
|
|
|
|
void BaseFinalRelease() { }
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
VirtualBoxBase(); // : _lock(nullptr) { }
|
|
|
|
~VirtualBoxBase();
|
|
|
|
|
|
|
|
virtual HRESULT addCaller(State *aState = NULL, bool aLimited = false);
|
|
|
|
virtual void releaseCaller();
|
|
|
|
|
|
|
|
virtual const char* getComponentName() const = 0;
|
|
|
|
|
|
|
|
static HRESULT handleUnexpectedExceptions(VirtualBoxBase *const aThis, RT_SRC_POS_DECL);
|
|
|
|
static HRESULT initializeComForThread(void);
|
2015-05-04 11:36:45 +02:00
|
|
|
static void uninitializeComForThread(void);
|
2014-09-23 13:01:47 +02:00
|
|
|
static void clearError(void);
|
|
|
|
|
|
|
|
HRESULT setError(HRESULT aResultCode);
|
|
|
|
HRESULT setError(HRESULT aResultCode, const char *pcsz, ...);
|
|
|
|
HRESULT setError(const com::ErrorInfo &ei);
|
|
|
|
|
|
|
|
static HRESULT setErrorInternal(HRESULT aResultCode,
|
|
|
|
const GUID &aIID,
|
|
|
|
const char *aComponent,
|
|
|
|
Utf8Str aText,
|
|
|
|
bool aWarning,
|
|
|
|
bool aLogIt);
|
|
|
|
|
|
|
|
virtual VBoxLockingClass getLockingClass() const
|
|
|
|
{
|
|
|
|
return LOCKCLASS_OTHEROBJECT;
|
|
|
|
}
|
|
|
|
|
|
|
|
RWLockHandle * lockHandle() const;
|
|
|
|
};
|
2015-02-22 19:04:55 +01:00
|
|
|
|
2015-05-04 11:36:45 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Dummy macro that is used to shut down Qt's lupdate tool warnings in some
|
|
|
|
* situations. This macro needs to be present inside (better at the very
|
|
|
|
* beginning) of the declaration of the class that inherits from
|
|
|
|
* VirtualBoxTranslatable, to make lupdate happy.
|
|
|
|
*/
|
|
|
|
#define Q_OBJECT
|
|
|
|
|
2014-09-23 13:01:47 +02:00
|
|
|
|
|
|
|
template <typename T>
|
2015-05-04 11:36:45 +02:00
|
|
|
class Shareable
|
|
|
|
{
|
2014-09-23 13:01:47 +02:00
|
|
|
|
|
|
|
private:
|
|
|
|
|
|
|
|
bool _verbose;
|
|
|
|
T * _obj;
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
Shareable<T> () : _verbose(false), _obj(nullptr) { }
|
|
|
|
|
|
|
|
/* operators */
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 19:07:09 +02:00
|
|
|
T * operator->() const { if (_verbose) Genode::log(__PRETTY_FUNCTION__, " called"); return _obj; }
|
2014-09-23 13:01:47 +02:00
|
|
|
|
|
|
|
bool isNull() const { return _obj == nullptr; }
|
|
|
|
bool operator!() const { return isNull(); }
|
|
|
|
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 19:07:09 +02:00
|
|
|
void allocate() { if (_verbose) Genode::log(__PRETTY_FUNCTION__, " called"); _obj = new T; }
|
|
|
|
void attach(T * t) { if (_verbose) Genode::log(__PRETTY_FUNCTION__, " called"); }
|
|
|
|
void attach(Shareable &s) { if (_verbose) Genode::log(__PRETTY_FUNCTION__, " called"); }
|
|
|
|
void share(const Shareable &s) { if (_verbose) Genode::log(__PRETTY_FUNCTION__, " called"); _obj = s._obj; }
|
|
|
|
void share(T * obj) { if (_verbose) Genode::log(__PRETTY_FUNCTION__, " called"); _obj = obj; }
|
|
|
|
void free() { if (_verbose) Genode::log(__PRETTY_FUNCTION__, " called"); }
|
|
|
|
void attachCopy(const T *) { if(_verbose) Genode::log(__PRETTY_FUNCTION__, " called"); }
|
|
|
|
void attachCopy(const Shareable &) { if (_verbose) Genode::log(__PRETTY_FUNCTION__, " called"); }
|
2014-09-23 13:01:47 +02:00
|
|
|
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 19:07:09 +02:00
|
|
|
T *data() const { if (_verbose) Genode::log(__PRETTY_FUNCTION__, " called"); return _obj; }
|
2014-09-23 13:01:47 +02:00
|
|
|
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 19:07:09 +02:00
|
|
|
bool isShared() const { if (_verbose) Genode::log(__PRETTY_FUNCTION__, " called"); return false; }
|
2014-09-23 13:01:47 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
template <typename T>
|
2015-05-04 11:36:45 +02:00
|
|
|
class Backupable : public Shareable<T>
|
|
|
|
{
|
2014-09-23 13:01:47 +02:00
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
Backupable() : Shareable<T>() { }
|
|
|
|
|
|
|
|
void backup() { }
|
|
|
|
void rollback() { }
|
|
|
|
void commit() { }
|
|
|
|
void commitCopy() { }
|
|
|
|
void assignCopy(const T *) { }
|
|
|
|
void assignCopy(const Backupable &) { }
|
|
|
|
|
|
|
|
HRESULT backupEx() { return S_OK; }
|
|
|
|
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 19:07:09 +02:00
|
|
|
T *backedUpData() const { Genode::log(__PRETTY_FUNCTION__, " called"); return nullptr; }
|
2014-09-23 13:01:47 +02:00
|
|
|
bool isBackedUp() const { return false; }
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Special version of the Assert macro to be used within VirtualBoxBase
|
|
|
|
* subclasses.
|
|
|
|
*
|
|
|
|
* In the debug build, this macro is equivalent to Assert.
|
|
|
|
* In the release build, this macro uses |setError(E_FAIL, ...)| to set the
|
|
|
|
* error info from the asserted expression.
|
|
|
|
*
|
|
|
|
* @see VirtualBoxBase::setError
|
|
|
|
*
|
|
|
|
* @param expr Expression which should be true.
|
|
|
|
*/
|
|
|
|
#if defined(DEBUG)
|
|
|
|
#define ComAssert(expr) Assert(expr)
|
|
|
|
#else
|
|
|
|
#define ComAssert(expr) \
|
|
|
|
do { \
|
|
|
|
if (RT_UNLIKELY(!(expr))) \
|
|
|
|
setError(E_FAIL, \
|
|
|
|
"Assertion failed: [%s] at '%s' (%d) in %s.\nPlease contact the product vendor!", \
|
|
|
|
#expr, __FILE__, __LINE__, __PRETTY_FUNCTION__); \
|
|
|
|
} while (0)
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Special version of the AssertFailed macro to be used within VirtualBoxBase
|
|
|
|
* subclasses.
|
|
|
|
*
|
|
|
|
* In the debug build, this macro is equivalent to AssertFailed.
|
|
|
|
* In the release build, this macro uses |setError(E_FAIL, ...)| to set the
|
|
|
|
* error info from the asserted expression.
|
|
|
|
*
|
|
|
|
* @see VirtualBoxBase::setError
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
#if defined(DEBUG)
|
|
|
|
#define ComAssertFailed() AssertFailed()
|
|
|
|
#else
|
|
|
|
#define ComAssertFailed() \
|
|
|
|
do { \
|
|
|
|
setError(E_FAIL, \
|
|
|
|
"Assertion failed: at '%s' (%d) in %s.\nPlease contact the product vendor!", \
|
|
|
|
__FILE__, __LINE__, __PRETTY_FUNCTION__); \
|
|
|
|
} while (0)
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Special version of the AssertMsg macro to be used within VirtualBoxBase
|
|
|
|
* subclasses.
|
|
|
|
*
|
|
|
|
* See ComAssert for more info.
|
|
|
|
*
|
|
|
|
* @param expr Expression which should be true.
|
|
|
|
* @param a printf argument list (in parenthesis).
|
|
|
|
*/
|
|
|
|
#if defined(DEBUG)
|
|
|
|
#define ComAssertMsg(expr, a) AssertMsg(expr, a)
|
|
|
|
#else
|
|
|
|
#define ComAssertMsg(expr, a) \
|
|
|
|
do { \
|
|
|
|
if (RT_UNLIKELY(!(expr))) \
|
|
|
|
setError(E_FAIL, \
|
|
|
|
"Assertion failed: [%s] at '%s' (%d) in %s.\n%s.\nPlease contact the product vendor!", \
|
|
|
|
#expr, __FILE__, __LINE__, __PRETTY_FUNCTION__, Utf8StrFmt a .c_str()); \
|
|
|
|
} while (0)
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Special version of the AssertComRC macro to be used within VirtualBoxBase
|
|
|
|
* subclasses.
|
|
|
|
*
|
|
|
|
* See ComAssert for more info.
|
|
|
|
*
|
|
|
|
* @param rc COM result code
|
|
|
|
*/
|
|
|
|
#if defined(DEBUG)
|
|
|
|
#define ComAssertComRC(rc) AssertComRC(rc)
|
|
|
|
#else
|
|
|
|
#define ComAssertComRC(rc) ComAssertMsg(SUCCEEDED(rc), ("COM RC = %Rhrc (0x%08X)", (rc), (rc)))
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Special version of the AssertMsgRC macro to be used within VirtualBoxBase
|
|
|
|
* subclasses.
|
|
|
|
*
|
|
|
|
* See ComAssert for more info.
|
|
|
|
*
|
|
|
|
* @param vrc VBox status code.
|
|
|
|
* @param msg printf argument list (in parenthesis).
|
|
|
|
*/
|
|
|
|
#if defined(DEBUG)
|
|
|
|
#define ComAssertMsgRC(vrc, msg) AssertMsgRC(vrc, msg)
|
|
|
|
#else
|
|
|
|
#define ComAssertMsgRC(vrc, msg) ComAssertMsg(RT_SUCCESS(vrc), msg)
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Special version of the AssertRC macro to be used within VirtualBoxBase
|
|
|
|
* subclasses.
|
|
|
|
*
|
|
|
|
* See ComAssert for more info.
|
|
|
|
*
|
|
|
|
* @param vrc VBox status code.
|
|
|
|
*/
|
|
|
|
#if defined(DEBUG)
|
|
|
|
#define ComAssertRC(vrc) AssertRC(vrc)
|
|
|
|
#else
|
|
|
|
#define ComAssertRC(vrc) ComAssertMsgRC(vrc, ("%Rra", vrc))
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/** Special version of ComAssert that returns ret if expr fails */
|
|
|
|
#define ComAssertRet(expr, ret) \
|
|
|
|
do { ComAssert(expr); if (!(expr)) return (ret); } while (0)
|
|
|
|
/** Special version of ComAssertMsg that returns ret if expr fails */
|
|
|
|
#define ComAssertMsgRet(expr, a, ret) \
|
|
|
|
do { ComAssertMsg(expr, a); if (!(expr)) return (ret); } while (0)
|
|
|
|
/** Special version of ComAssertComRC that returns ret if rc does not succeed */
|
|
|
|
#define ComAssertComRCRet(rc, ret) \
|
|
|
|
do { ComAssertComRC(rc); if (!SUCCEEDED(rc)) return (ret); } while (0)
|
|
|
|
/** Special version of ComAssertMsg that evaluates eval and breaks if expr fails */
|
|
|
|
#define ComAssertMsgBreak(expr, a, eval) \
|
|
|
|
if (1) { ComAssertMsg(expr, a); if (!(expr)) { eval; break; } } else do {} while (0)
|
|
|
|
/** Special version of ComAssert that evaluates eval and throws it if expr fails */
|
|
|
|
#define ComAssertThrow(expr, eval) \
|
|
|
|
do { ComAssert(expr); if (!(expr)) { throw (eval); } } while (0)
|
|
|
|
/** Special version of ComAssertRC that evaluates eval and throws it if vrc does not succeed */
|
|
|
|
#define ComAssertRCThrow(vrc, eval) \
|
|
|
|
do { ComAssertRC(vrc); if (!RT_SUCCESS(vrc)) { throw (eval); } } while (0)
|
|
|
|
/** Special version of ComAssertFailed that returns ret */
|
|
|
|
#define ComAssertFailedRet(ret) \
|
|
|
|
do { ComAssertFailed(); return (ret); } while (0)
|
|
|
|
/** Special version of ComAssertFailed that returns ret */
|
|
|
|
#define ComAssertFailedRet(ret) \
|
|
|
|
do { ComAssertFailed(); return (ret); } while (0)
|
|
|
|
/** Special version of ComAssertRC that returns ret if vrc does not succeed */
|
|
|
|
#define ComAssertRCRet(vrc, ret) \
|
|
|
|
do { ComAssertRC(vrc); if (!RT_SUCCESS(vrc)) return (ret); } while (0)
|
|
|
|
/** Special version of ComAssertComRC that just throws rc if rc does not succeed */
|
|
|
|
#define ComAssertComRCThrowRC(rc) \
|
|
|
|
do { ComAssertComRC(rc); if (!SUCCEEDED(rc)) { throw rc; } } while (0)
|
|
|
|
/** Special version of ComAssertComRC that returns rc if rc does not succeed */
|
|
|
|
#define ComAssertComRCRetRC(rc) \
|
|
|
|
do { ComAssertComRC(rc); if (!SUCCEEDED(rc)) return (rc); } while (0)
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Checks that the pointer argument is not NULL and returns E_INVALIDARG +
|
|
|
|
* extended error info on failure.
|
|
|
|
* @param arg Input pointer-type argument (strings, interface pointers...)
|
|
|
|
*/
|
|
|
|
#define CheckComArgNotNull(arg) \
|
|
|
|
do { \
|
|
|
|
if (RT_UNLIKELY((arg) == NULL)) \
|
|
|
|
return setError(E_INVALIDARG, tr("Argument %s is NULL"), #arg); \
|
|
|
|
} while (0)
|
|
|
|
|
2017-04-26 11:19:40 +02:00
|
|
|
/**
|
|
|
|
* Checks that the pointer argument is a valid pointer or NULL and returns
|
|
|
|
* E_INVALIDARG + extended error info on failure.
|
|
|
|
* @param arg Input pointer-type argument (strings, interface pointers...)
|
|
|
|
*/
|
|
|
|
#define CheckComArgMaybeNull(arg) \
|
|
|
|
do { \
|
|
|
|
if (RT_UNLIKELY(!RT_VALID_PTR(arg) && (arg) != NULL)) \
|
|
|
|
return setError(E_INVALIDARG, tr("Argument %s is an invalid pointer"), #arg); \
|
|
|
|
} while (0)
|
|
|
|
|
2014-09-23 13:01:47 +02:00
|
|
|
/**
|
|
|
|
* Checks that the given expression (that must involve the argument) is true and
|
|
|
|
* returns E_INVALIDARG + extended error info on failure.
|
|
|
|
* @param arg Argument.
|
|
|
|
* @param expr Expression to evaluate.
|
|
|
|
*/
|
|
|
|
#define CheckComArgExpr(arg, expr) \
|
|
|
|
do { \
|
|
|
|
if (RT_UNLIKELY(!(expr))) \
|
|
|
|
return setError(E_INVALIDARG, \
|
|
|
|
tr("Argument %s is invalid (must be %s)"), #arg, #expr); \
|
|
|
|
} while (0)
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Checks that the given pointer to an output argument is valid and returns
|
|
|
|
* E_POINTER + extended error info otherwise.
|
|
|
|
* @param arg Pointer argument.
|
|
|
|
*/
|
|
|
|
#define CheckComArgOutPointerValid(arg) \
|
|
|
|
do { \
|
|
|
|
if (RT_UNLIKELY(!VALID_PTR(arg))) \
|
|
|
|
return setError(E_POINTER, \
|
|
|
|
tr("Output argument %s points to invalid memory location (%p)"), \
|
|
|
|
#arg, (void *)(arg)); \
|
|
|
|
} while (0)
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Checks that a string input argument is valid (not NULL or obviously invalid
|
|
|
|
* pointer), returning E_INVALIDARG + extended error info if invalid.
|
|
|
|
* @param a_bstrIn Input string argument (IN_BSTR).
|
|
|
|
*/
|
|
|
|
#define CheckComArgStr(a_bstrIn) \
|
|
|
|
do { \
|
|
|
|
IN_BSTR const bstrInCheck = (a_bstrIn); /* type check */ \
|
|
|
|
if (RT_UNLIKELY(!RT_VALID_PTR(bstrInCheck))) \
|
|
|
|
return setError(E_INVALIDARG, tr("Argument %s is an invalid pointer"), #a_bstrIn); \
|
|
|
|
} while (0)
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Checks that the string argument is not a NULL, a invalid pointer or an empty
|
|
|
|
* string, returning E_INVALIDARG + extended error info on failure.
|
|
|
|
* @param a_bstrIn Input string argument (BSTR etc.).
|
|
|
|
*/
|
|
|
|
#define CheckComArgStrNotEmptyOrNull(a_bstrIn) \
|
|
|
|
do { \
|
|
|
|
IN_BSTR const bstrInCheck = (a_bstrIn); /* type check */ \
|
|
|
|
if (RT_UNLIKELY(!RT_VALID_PTR(bstrInCheck) || *(bstrInCheck) == '\0')) \
|
|
|
|
return setError(E_INVALIDARG, tr("Argument %s is empty or an invalid pointer"), #a_bstrIn); \
|
|
|
|
} while (0)
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Checks that the given pointer to an output safe array argument is valid and
|
|
|
|
* returns E_POINTER + extended error info otherwise.
|
|
|
|
* @param arg Safe array argument.
|
|
|
|
*/
|
|
|
|
#define CheckComArgOutSafeArrayPointerValid(arg) \
|
|
|
|
do { \
|
|
|
|
if (RT_UNLIKELY(ComSafeArrayOutIsNull(arg))) \
|
|
|
|
return setError(E_POINTER, \
|
|
|
|
tr("Output argument %s points to invalid memory location (%p)"), \
|
|
|
|
#arg, (void*)(arg)); \
|
|
|
|
} while (0)
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Checks that safe array argument is not NULL and returns E_INVALIDARG +
|
|
|
|
* extended error info on failure.
|
|
|
|
* @param arg Input safe array argument (strings, interface pointers...)
|
|
|
|
*/
|
|
|
|
#define CheckComArgSafeArrayNotNull(arg) \
|
|
|
|
do { \
|
|
|
|
if (RT_UNLIKELY(ComSafeArrayInIsNull(arg))) \
|
|
|
|
return setError(E_INVALIDARG, tr("Argument %s is NULL"), #arg); \
|
|
|
|
} while (0)
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Sets the extended error info and returns E_NOTIMPL.
|
|
|
|
*/
|
|
|
|
#define ReturnComNotImplemented() \
|
|
|
|
do { \
|
|
|
|
return setError(E_NOTIMPL, tr("Method %s is not implemented"), __FUNCTION__); \
|
|
|
|
} while (0)
|
|
|
|
|
|
|
|
|
2015-05-04 11:36:45 +02:00
|
|
|
#define DECLARE_EMPTY_CTOR_DTOR(X) public: X(); ~X();
|
2014-09-23 13:01:47 +02:00
|
|
|
|
2015-05-04 11:36:45 +02:00
|
|
|
#define DEFINE_EMPTY_CTOR_DTOR(X) X::X() {} X::~X() {}
|
2014-09-23 13:01:47 +02:00
|
|
|
|
|
|
|
|
|
|
|
#define VIRTUALBOXBASE_ADD_VIRTUAL_COMPONENT_METHODS(cls, iface) \
|
|
|
|
virtual const GUID& getClassIID() const \
|
|
|
|
{ \
|
|
|
|
return cls::getStaticClassIID(); \
|
|
|
|
} \
|
|
|
|
static const GUID& getStaticClassIID() \
|
|
|
|
{ \
|
|
|
|
return COM_IIDOF(iface); \
|
|
|
|
} \
|
|
|
|
virtual const char* getComponentName() const \
|
|
|
|
{ \
|
|
|
|
return cls::getStaticComponentName(); \
|
|
|
|
} \
|
|
|
|
static const char* getStaticComponentName() \
|
|
|
|
{ \
|
|
|
|
return #cls; \
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* VIRTUALBOXBASE_ADD_ERRORINFO_SUPPORT:
|
|
|
|
* This macro must be used once in the declaration of any class derived
|
|
|
|
* from VirtualBoxBase. It implements the pure virtual getClassIID() and
|
|
|
|
* getComponentName() methods. If this macro is not present, instances
|
|
|
|
* of a class derived from VirtualBoxBase cannot be instantiated.
|
|
|
|
*
|
|
|
|
* @param X The class name, e.g. "Class".
|
|
|
|
* @param IX The interface name which this class implements, e.g. "IClass".
|
|
|
|
*/
|
|
|
|
#define VIRTUALBOXBASE_ADD_ERRORINFO_SUPPORT(cls, iface) \
|
|
|
|
VIRTUALBOXBASE_ADD_VIRTUAL_COMPONENT_METHODS(cls, iface)
|
|
|
|
|
|
|
|
#include "GenodeImpl.h"
|
|
|
|
|
|
|
|
#endif // !____H_VIRTUALBOXBASEIMPL
|