Implement vboxUniformedAPI for each vbox API version.
Some common code and definitions are moved to
vbox_common.c and vbox_uniformed_api.h.
---
src/vbox/vbox_tmpl.c | 419 +++++++++++++++++++++++++++++---------------------
1 file changed, 245 insertions(+), 174 deletions(-)
diff --git a/src/vbox/vbox_tmpl.c b/src/vbox/vbox_tmpl.c
index 4ba9ad7..7d01308 100644
--- a/src/vbox/vbox_tmpl.c
+++ b/src/vbox/vbox_tmpl.c
@@ -89,7 +89,7 @@
/* Include this *last* or we'll get the wrong vbox_CAPI_*.h. */
#include "vbox_glue.h"
-
+#include "vbox_uniformed_api.h"
#define VIR_FROM_THIS VIR_FROM_VBOX
@@ -189,7 +189,7 @@ if (strUtf16) {\
#define DEBUGUUID(msg, iid) \
{\
- VIR_DEBUG(msg ": {%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",\
+ VIR_DEBUG("%s: {%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}", msg,\
(unsigned)(iid)->m0,\
(unsigned)(iid)->m1,\
(unsigned)(iid)->m2,\
@@ -203,42 +203,6 @@ if (strUtf16) {\
(unsigned)(iid)->m3[7]);\
}\
-typedef struct {
- virMutex lock;
- unsigned long version;
-
- virCapsPtr caps;
- virDomainXMLOptionPtr xmlopt;
-
- IVirtualBox *vboxObj;
- ISession *vboxSession;
-
- /** Our version specific API table pointer. */
- PCVBOXXPCOM pFuncs;
-
-#if VBOX_API_VERSION == 2002000
-
-} vboxGlobalData;
-
-#else /* !(VBOX_API_VERSION == 2002000) */
-
- /* Async event handling */
- virObjectEventStatePtr domainEvents;
- int fdWatch;
-
-# if VBOX_API_VERSION <= 3002000
- /* IVirtualBoxCallback is used in VirtualBox 3.x only */
- IVirtualBoxCallback *vboxCallback;
-# endif /* VBOX_API_VERSION <= 3002000 */
-
- nsIEventQueue *vboxQueue;
- int volatile vboxCallBackRefCount;
-
- /* pointer back to the connection */
- virConnectPtr conn;
-
-} vboxGlobalData;
-
/* g_pVBoxGlobalData has to be global variable,
* there is no other way to make the callbacks
* work other then having g_pVBoxGlobalData as
@@ -249,6 +213,8 @@ typedef struct {
* them that way
*/
+#if VBOX_API_VERSION > 2002000
+
static vboxGlobalData *g_pVBoxGlobalData = NULL;
#endif /* !(VBOX_API_VERSION == 2002000) */
@@ -386,13 +352,10 @@ static void nsIDFromChar(nsID *iid, const unsigned char *uuid)
typedef struct _vboxIID_v2_x_WIN32 vboxIID;
typedef struct _vboxIID_v2_x_WIN32 vboxIID_v2_x_WIN32;
-struct _vboxIID_v2_x_WIN32 {
- /* IID is represented by a GUID value. */
- GUID value;
-};
-
# define VBOX_IID_INITIALIZER { { 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0 } } }
+# define IIDU(name) (iidu->vboxIID_v2_x_WIN32.name)
+
static void
vboxIIDUnalloc_v2_x_WIN32(vboxGlobalData *data ATTRIBUTE_UNUSED,
vboxIID_v2_x_WIN32 *iid ATTRIBUTE_UNUSED)
@@ -401,6 +364,13 @@ vboxIIDUnalloc_v2_x_WIN32(vboxGlobalData *data ATTRIBUTE_UNUSED,
}
static void
+_vboxIIDUnalloc_v2_x_WIN32(vboxGlobalData *data ATTRIBUTE_UNUSED,
+ vboxIIDUnion *iid ATTRIBUTE_UNUSED)
+{
+ /* Nothing to free */
+}
+
+static void
vboxIIDToUUID_v2_x_WIN32(vboxIID_v2_x_WIN32 *iid, unsigned char *uuid)
{
nsIDtoChar(uuid, (nsID *)&iid->value);
@@ -415,6 +385,13 @@ vboxIIDFromUUID_v2_x_WIN32(vboxGlobalData *data, vboxIID_v2_x_WIN32
*iid,
nsIDFromChar((nsID *)&iid->value, uuid);
}
+static void
+_vboxIIDFromUUID_v2_x_WIN32(vboxGlobalData *data, vboxIIDUnion *iidu,
+ const unsigned char *uuid)
+{
+ vboxIIDFromUUID_v2_x_WIN32(data, &iidu->vboxIID_v2_x_WIN32, uuid);
+}
+
static bool
vboxIIDIsEqual_v2_x_WIN32(vboxIID_v2_x_WIN32 *iid1, vboxIID_v2_x_WIN32 *iid2)
{
@@ -432,6 +409,7 @@ vboxIIDFromArrayItem_v2_x_WIN32(vboxGlobalData *data,
vboxIID_v2_x_WIN32 *iid,
memcpy(&iid->value, &items[idx], sizeof(GUID));
}
+
# define vboxIIDUnalloc(iid) vboxIIDUnalloc_v2_x_WIN32(data, iid)
# define vboxIIDToUUID(iid, uuid) vboxIIDToUUID_v2_x_WIN32(iid, uuid)
# define vboxIIDFromUUID(iid, uuid) vboxIIDFromUUID_v2_x_WIN32(data, iid, uuid)
@@ -440,23 +418,16 @@ vboxIIDFromArrayItem_v2_x_WIN32(vboxGlobalData *data,
vboxIID_v2_x_WIN32 *iid,
vboxIIDFromArrayItem_v2_x_WIN32(data, iid, array, idx)
# define DEBUGIID(msg, iid) DEBUGUUID(msg, (nsID *)&(iid))
+
# else /* !WIN32 */
typedef struct _vboxIID_v2_x vboxIID;
typedef struct _vboxIID_v2_x vboxIID_v2_x;
-struct _vboxIID_v2_x {
- /* IID is represented by a pointer to a nsID. */
- nsID *value;
-
- /* backing is used in cases where we need to create or copy an IID.
- * We cannot allocate memory that can be freed by ComUnallocMem.
- * Therefore, we use this stack allocated nsID instead. */
- nsID backing;
-};
-
# define VBOX_IID_INITIALIZER { NULL, { 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0 } } }
+# define IIDU(name) (iidu->vboxIID_v2_x.name)
+
static void
vboxIIDUnalloc_v2_x(vboxGlobalData *data, vboxIID_v2_x *iid)
{
@@ -472,6 +443,12 @@ vboxIIDUnalloc_v2_x(vboxGlobalData *data, vboxIID_v2_x *iid)
}
static void
+_vboxIIDUnalloc_v2_x(vboxGlobalData *data, vboxIIDUnion *iidu)
+{
+ vboxIIDUnalloc_v2_x(data, &iidu->vboxIID_v2_x);
+}
+
+static void
vboxIIDToUUID_v2_x(vboxIID_v2_x *iid, unsigned char *uuid)
{
nsIDtoChar(uuid, iid->value);
@@ -489,6 +466,13 @@ vboxIIDFromUUID_v2_x(vboxGlobalData *data, vboxIID_v2_x *iid,
nsIDFromChar(iid->value, uuid);
}
+static void
+_vboxIIDFromUUID_v2_x(vboxGlobalData *data, vboxIIDUnion *iidu,
+ const unsigned char *uuid)
+{
+ vboxIIDFromUUID_v2_x(data, &iidu->vboxIID_v2_x, uuid);
+}
+
static bool
vboxIIDIsEqual_v2_x(vboxIID_v2_x *iid1, vboxIID_v2_x *iid2)
{
@@ -506,6 +490,7 @@ vboxIIDFromArrayItem_v2_x(vboxGlobalData *data, vboxIID_v2_x *iid,
memcpy(iid->value, array->items[idx], sizeof(nsID));
}
+
# define vboxIIDUnalloc(iid) vboxIIDUnalloc_v2_x(data, iid)
# define vboxIIDToUUID(iid, uuid) vboxIIDToUUID_v2_x(iid, uuid)
# define vboxIIDFromUUID(iid, uuid) vboxIIDFromUUID_v2_x(data, iid, uuid)
@@ -514,6 +499,7 @@ vboxIIDFromArrayItem_v2_x(vboxGlobalData *data, vboxIID_v2_x *iid,
vboxIIDFromArrayItem_v2_x(data, iid, array, idx)
# define DEBUGIID(msg, iid) DEBUGUUID(msg, iid)
+
# endif /* !WIN32 */
#else /* VBOX_API_VERSION != 2002000 */
@@ -521,16 +507,10 @@ vboxIIDFromArrayItem_v2_x(vboxGlobalData *data, vboxIID_v2_x *iid,
typedef struct _vboxIID_v3_x vboxIID;
typedef struct _vboxIID_v3_x vboxIID_v3_x;
-struct _vboxIID_v3_x {
- /* IID is represented by a UTF-16 encoded UUID in string form. */
- PRUnichar *value;
-
- /* owner indicates if we own the value and need to free it. */
- bool owner;
-};
-
# define VBOX_IID_INITIALIZER { NULL, true }
+# define IIDU(name) (iidu->vboxIID_v3_x.name)
+
static void
vboxIIDUnalloc_v3_x(vboxGlobalData *data, vboxIID_v3_x *iid)
{
@@ -543,6 +523,12 @@ vboxIIDUnalloc_v3_x(vboxGlobalData *data, vboxIID_v3_x *iid)
}
static void
+_vboxIIDUnalloc_v3_x(vboxGlobalData *data, vboxIIDUnion *iidu)
+{
+ vboxIIDUnalloc_v3_x(data, &iidu->vboxIID_v3_x);
+}
+
+static void
vboxIIDToUUID_v3_x(vboxGlobalData *data, vboxIID_v3_x *iid,
unsigned char *uuid)
{
@@ -568,6 +554,13 @@ vboxIIDFromUUID_v3_x(vboxGlobalData *data, vboxIID_v3_x *iid,
data->pFuncs->pfnUtf8ToUtf16(utf8, &iid->value);
}
+static void
+_vboxIIDFromUUID_v3_x(vboxGlobalData *data, vboxIIDUnion *iidu,
+ const unsigned char *uuid)
+{
+ vboxIIDFromUUID_v3_x(data, &iidu->vboxIID_v3_x, uuid);
+}
+
static bool
vboxIIDIsEqual_v3_x(vboxGlobalData *data, vboxIID_v3_x *iid1,
vboxIID_v3_x *iid2)
@@ -606,6 +599,7 @@ vboxIIDFromArrayItem_v3_x(vboxGlobalData *data, vboxIID_v3_x *iid,
vboxIIDFromArrayItem_v3_x(data, iid, array, idx)
# define DEBUGIID(msg, strUtf16) DEBUGPRUnichar(msg, strUtf16)
+
# if VBOX_API_VERSION >= 3001000
/**
@@ -826,6 +820,196 @@ static PRUnichar *PRUnicharFromInt(int n) {
#endif /* !(VBOX_API_VERSION == 2002000) */
+/* Begin of vboxUniformedAPI */
+
+static int _pfnInitialize(vboxGlobalData *data)
+{
+ data->pFuncs = g_pfnGetFunctions(VBOX_XPCOMC_VERSION);
+ if (data->pFuncs == NULL)
+ return -1;
+#if VBOX_XPCOMC_VERSION == 0x00010000U
+ data->pFuncs->pfnComInitialize(&data->vboxObj,
&data->vboxSession);
+#else /* !(VBOX_XPCOMC_VERSION == 0x00010000U) */
+ data->pFuncs->pfnComInitialize(IVIRTUALBOX_IID_STR, &data->vboxObj,
ISESSION_IID_STR, &data->vboxSession);
+#endif /* !(VBOX_XPCOMC_VERSION == 0x00010000U) */
+ return 0;
+}
+
+static int
+_initializeFWatch(vboxGlobalData *data ATTRIBUTE_UNUSED)
+{
+#if (VBOX_XPCOMC_VERSION == 0x00010000U) || (VBOX_API_VERSION == 2002000)
+ /* No event queue functionality in 2.2.* as of now */
+ VIR_WARN("There is no fWatch initical in current version");
+#else /* (VBOX_XPCOMC_VERSION != 0x00010000U && VBOX_API_VERSION != 2002000) */
+ /* Initialize the fWatch needed for Event Callbacks */
+ data->fdWatch = -1;
+ data->pFuncs->pfnGetEventQueue(&data->vboxQueue);
+ if (data->vboxQueue == NULL) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("nsIEventQueue object is null"));
+ return -1;
+ }
+#endif /* (VBOX_XPCOMC_VERSION != 0x00010000U && VBOX_API_VERSION != 2002000) */
+ return 0;
+}
+
+static nsresult
+_sessionGetConsole(ISession *session, IConsole **console)
+{
+ return session->vtbl->GetConsole(session, console);
+}
+
+static nsresult
+_consoleSaveState(IConsole *console, IProgress **progress)
+{
+ return console->vtbl->SaveState(console, progress);
+}
+
+static nsresult
+_progressWaitForCompletion(IProgress *progress, PRInt32 timeout)
+{
+ return progress->vtbl->WaitForCompletion(progress, timeout);
+}
+
+static nsresult _nsisupportsRelease(void *Ihandle)
+{
+ /* It is safety to convert a pointer from IVirtual(or structs
+ * like this) to nsISupports*/
+ nsISupports *nsi = (nsISupports *)Ihandle;
+ return nsi->vtbl->Release(nsi);
+}
+
+#if VBOX_API_VERSION == 2002000
+
+static nsresult
+_progressGetResultCode(IProgress *progress, resultCodeUnion *resultCode)
+{
+ return progress->vtbl->GetResultCode(progress,
&resultCode->uResultCode);
+}
+
+static void _initializeVboxIID(vboxIIDUnion *iidu)
+{
+ memset(iidu, 0, sizeof(vboxIIDUnion));
+}
+
+static void _DEBUGIID(const char *msg, vboxIIDUnion *iidu)
+{
+# ifdef WIN32
+ DEBUGUUID(msg, (nsID *)&IIDU(value));
+# else /* !WIN32 */
+ DEBUGUUID(msg, IIDU(value));
+# endif /* !WIN32 */
+}
+
+#else /* VBOX_API_VERSION != 2002000 */
+
+static nsresult
+_progressGetResultCode(IProgress *progress, resultCodeUnion *resultCode)
+{
+ return progress->vtbl->GetResultCode(progress,
&resultCode->resultCode);
+}
+
+static void _initializeVboxIID(vboxIIDUnion *iidu)
+{
+ memset(iidu, 0, sizeof(vboxIIDUnion));
+ IIDU(owner) = true;
+}
+
+static void _DEBUGIID(const char *msg, vboxIIDUnion *iidu)
+{
+ DEBUGPRUnichar(msg, IIDU(value));
+}
+
+#endif /* VBOX_API_VERSION != 2002000 */
+
+#if VBOX_API_VERSION < 4000000
+
+static nsresult
+_objectGetMachine(vboxGlobalData *data, vboxIIDUnion *iidu, IMachine **machine)
+{
+ return data->vboxObj->vtbl->GetMachine(data->vboxObj, IIDU(value),
machine);
+}
+
+static nsresult
+_sessionOpenExisting(vboxGlobalData *data, vboxIIDUnion *iidu, IMachine *machine
ATTRIBUTE_UNUSED)
+{
+ return data->vboxObj->vtbl->OpenExistingSession(data->vboxObj,
data->vboxSession, IIDU(value));
+}
+
+static nsresult
+_sessionClose(ISession *session)
+{
+ return session->vtbl->Close(session);
+}
+
+#else /* VBOX_API_VERSION >= 4000000 */
+
+static nsresult
+_objectGetMachine(vboxGlobalData *data, vboxIIDUnion *iidu, IMachine **machine)
+{
+ return data->vboxObj->vtbl->FindMachine(data->vboxObj, IIDU(value),
machine);
+}
+
+static nsresult
+_sessionOpenExisting(vboxGlobalData *data, vboxIIDUnion *iidu ATTRIBUTE_UNUSED, IMachine
*machine)
+{
+ return machine->vtbl->LockMachine(machine, data->vboxSession,
LockType_Shared);
+}
+
+static nsresult
+_sessionClose(ISession *session)
+{
+ return session->vtbl->UnlockMachine(session);
+}
+
+#endif /* VBOX_API_VERSION >= 4000000 */
+
+vboxUniformedAPI NAME(UniformedAPI) = {
+ .APIVersion = VBOX_API_VERSION,
+ .XPCOMCVersion = VBOX_XPCOMC_VERSION,
+ .pfnInitialize = _pfnInitialize,
+ .initializeFWatch = _initializeFWatch,
+ .initializeVboxIID = _initializeVboxIID,
+ .objectGetMachine = _objectGetMachine,
+ .sessionOpenExisting = _sessionOpenExisting,
+ .sessionClose = _sessionClose,
+ .sessionGetConsole = _sessionGetConsole,
+ .consoleSaveState = _consoleSaveState,
+ .progressWaitForCompletion = _progressWaitForCompletion,
+ .progressGetResultCode = _progressGetResultCode,
+ .nsisupportsRelease = _nsisupportsRelease,
+#if VBOX_API_VERSION == 2002000
+# ifdef WIN32
+ .vboxIIDUnalloc = _vboxIIDUnalloc_v2_x_WIN32,
+ .vboxIIDFromUUID = _vboxIIDFromUUID_v2_x_WIN32,
+# else /* !WIN32 */
+ .vboxIIDUnalloc = _vboxIIDUnalloc_v2_x,
+ .vboxIIDFromUUID = _vboxIIDFromUUID_v2_x,
+# endif /* !WIN32 */
+#else /* VBOX_API_VERSION != 2002000 */
+ .vboxIIDUnalloc = _vboxIIDUnalloc_v3_x,
+ .vboxIIDFromUUID = _vboxIIDFromUUID_v3_x,
+#endif /* VBOX_API_VERSION != 2002000 */
+ .DEBUGIID = _DEBUGIID,
+
+#if (VBOX_XPCOMC_VERSION == 0x00010000U) || (VBOX_API_VERSION == 2002000)
+ /* No event queue functionality in 2.2.* as of now */
+ .fWatchNeedInitialize = 0,
+#else /* (VBOX_XPCOMC_VERSION != 0x00010000U && VBOX_API_VERSION != 2002000) */
+ .fWatchNeedInitialize = 1,
+#endif /* (VBOX_XPCOMC_VERSION != 0x00010000U && VBOX_API_VERSION != 2002000) */
+
+#if VBOX_API_VERSION >= 4000000
+ /* Get machine for the call to VBOX_SESSION_OPEN_EXISTING */
+ .getMachineForSession = 1,
+#else /* VBOX_API_VERSION < 4000000 */
+ .getMachineForSession = 0,
+#endif /* VBOX_API_VERSION < 4000000 */
+};
+
+/* End of vboxUniformedAPI and Begin of common codes */
+
static PRUnichar *
vboxSocketFormatAddrUtf16(vboxGlobalData *data, virSocketAddrPtr addr)
{
@@ -915,58 +1099,6 @@ static virCapsPtr vboxCapsInit(void)
return NULL;
}
-static int
-vboxInitialize(vboxGlobalData *data)
-{
- data->pFuncs = g_pfnGetFunctions(VBOX_XPCOMC_VERSION);
-
- if (data->pFuncs == NULL)
- goto cleanup;
-
-#if VBOX_XPCOMC_VERSION == 0x00010000U
- data->pFuncs->pfnComInitialize(&data->vboxObj,
&data->vboxSession);
-#else /* !(VBOX_XPCOMC_VERSION == 0x00010000U) */
- data->pFuncs->pfnComInitialize(IVIRTUALBOX_IID_STR, &data->vboxObj,
- ISESSION_IID_STR, &data->vboxSession);
-
-# if VBOX_API_VERSION == 2002000
-
- /* No event queue functionality in 2.2.* as of now */
-
-# else /* !(VBOX_API_VERSION == 2002000) */
-
- /* Initial the fWatch needed for Event Callbacks */
- data->fdWatch = -1;
-
- data->pFuncs->pfnGetEventQueue(&data->vboxQueue);
-
- if (data->vboxQueue == NULL) {
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("nsIEventQueue object is null"));
- goto cleanup;
- }
-
-# endif /* !(VBOX_API_VERSION == 2002000) */
-#endif /* !(VBOX_XPCOMC_VERSION == 0x00010000U) */
-
- if (data->vboxObj == NULL) {
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("IVirtualBox object is null"));
- goto cleanup;
- }
-
- if (data->vboxSession == NULL) {
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("ISession object is null"));
- goto cleanup;
- }
-
- return 0;
-
- cleanup:
- return -1;
-}
-
static int vboxExtractVersion(vboxGlobalData *data)
{
int ret = -1;
@@ -2093,67 +2225,6 @@ vboxDomainGetState(virDomainPtr dom,
return ret;
}
-static int vboxDomainSave(virDomainPtr dom, const char *path ATTRIBUTE_UNUSED)
-{
- VBOX_OBJECT_CHECK(dom->conn, int, -1);
- IConsole *console = NULL;
- vboxIID iid = VBOX_IID_INITIALIZER;
- IMachine *machine = NULL;
- nsresult rc;
-
- /* VirtualBox currently doesn't support saving to a file
- * at a location other then the machine folder and thus
- * setting path to ATTRIBUTE_UNUSED for now, will change
- * this behaviour once get the VirtualBox API in right
- * shape to do this
- */
-
- /* Open a Session for the machine */
- vboxIIDFromUUID(&iid, dom->uuid);
-#if VBOX_API_VERSION >= 4000000
- /* Get machine for the call to VBOX_SESSION_OPEN_EXISTING */
- rc = VBOX_OBJECT_GET_MACHINE(iid.value, &machine);
- if (NS_FAILED(rc)) {
- virReportError(VIR_ERR_NO_DOMAIN, "%s",
- _("no domain with matching uuid"));
- return -1;
- }
-#endif
-
- rc = VBOX_SESSION_OPEN_EXISTING(iid.value, machine);
- if (NS_SUCCEEDED(rc)) {
- rc = data->vboxSession->vtbl->GetConsole(data->vboxSession,
&console);
- if (NS_SUCCEEDED(rc) && console) {
- IProgress *progress = NULL;
-
- console->vtbl->SaveState(console, &progress);
-
- if (progress) {
-#if VBOX_API_VERSION == 2002000
- nsresult resultCode;
-#else
- PRInt32 resultCode;
-#endif
-
- progress->vtbl->WaitForCompletion(progress, -1);
- progress->vtbl->GetResultCode(progress, &resultCode);
- if (NS_SUCCEEDED(resultCode)) {
- ret = 0;
- }
- VBOX_RELEASE(progress);
- }
- VBOX_RELEASE(console);
- }
- VBOX_SESSION_CLOSE();
- }
-
- DEBUGIID("UUID of machine being saved:", iid.value);
-
- VBOX_RELEASE(machine);
- vboxIIDUnalloc(&iid);
- return ret;
-}
-
static int
vboxDomainSetVcpusFlags(virDomainPtr dom, unsigned int nvcpus,
unsigned int flags)
--
1.7.9.5