All vbox objects are child objects from the nsISupports in vbox's
C++ API version. Since the CAPI is generated from the C++ API, I
kept their relationship here, by the definitations below:
typedef struct nsISupports nsISupports;
typedef nsISupports IVirtualBox;
typedef nsISupports ISession;
and so on...
So, when calling the API from nsISupports, we don't need to do
typecasting, and things work still work well.
---
src/vbox/vbox_common.c | 95 ++++++++++++
src/vbox/vbox_common.h | 45 +++++-
src/vbox/vbox_tmpl.c | 342 +++++++++++++++++++++++++++++++----------
src/vbox/vbox_uniformed_api.h | 82 ++++++++++
4 files changed, 477 insertions(+), 87 deletions(-)
diff --git a/src/vbox/vbox_common.c b/src/vbox/vbox_common.c
index 06f1524..28d8668 100644
--- a/src/vbox/vbox_common.c
+++ b/src/vbox/vbox_common.c
@@ -42,6 +42,9 @@
VIR_LOG_INIT("vbox.vbox_common");
+#define RC_SUCCEEDED(rc) NS_SUCCEEDED(rc.resultCode)
+#define RC_FAILED(rc) NS_FAILED(rc.resultCode)
+
#define VBOX_UTF16_FREE(arg) \
do { \
if (arg) { \
@@ -69,6 +72,31 @@ VIR_LOG_INIT("vbox.vbox_common");
#define VBOX_UTF16_TO_UTF8(arg1, arg2) gVBoxAPI.UPFN.Utf16ToUtf8(data->pFuncs, arg1,
arg2)
#define VBOX_UTF8_TO_UTF16(arg1, arg2) gVBoxAPI.UPFN.Utf8ToUtf16(data->pFuncs, arg1,
arg2)
+#define VBOX_RELEASE(arg) \
+ do { \
+ if (arg) { \
+ gVBoxAPI.nsUISupports.Release((void *)arg); \
+ (arg) = NULL; \
+ } \
+ } while (0)
+
+#define VBOX_OBJECT_CHECK(conn, type, value) \
+vboxGlobalData *data = conn->privateData;\
+type ret = value;\
+if (!data->vboxObj) {\
+ return ret;\
+}
+
+#define vboxIIDUnalloc(iid) gVBoxAPI.UIID.vboxIIDUnalloc(data, iid)
+#define vboxIIDToUUID(iid, uuid) gVBoxAPI.UIID.vboxIIDToUUID(data, iid,
uuid)
+#define vboxIIDFromUUID(iid, uuid) gVBoxAPI.UIID.vboxIIDFromUUID(data, iid,
uuid)
+#define vboxIIDIsEqual(iid1, iid2) gVBoxAPI.UIID.vboxIIDIsEqual(data, iid1,
iid2)
+#define DEBUGIID(msg, iid) gVBoxAPI.UIID.DEBUGIID(msg, iid)
+#define vboxIIDFromArrayItem(iid, array, idx) \
+ gVBoxAPI.UIID.vboxIIDFromArrayItem(data, iid, array, idx)
+
+#define VBOX_IID_INITIALIZE(iid) gVBoxAPI.UIID.vboxIIDInitialize(iid)
+
/* global vbox API, used for all common codes. */
static vboxUniformedAPI gVBoxAPI;
@@ -103,6 +131,22 @@ int vboxRegisterUniformedAPI(uint32_t uVersion)
return 0;
}
+static int openSessionForMachine(vboxGlobalData *data, const unsigned char *dom_uuid,
vboxIIDUnion *iid,
+ IMachine **machine, bool checkflag)
+{
+ VBOX_IID_INITIALIZE(iid);
+ vboxIIDFromUUID(iid, dom_uuid);
+ if (!checkflag || gVBoxAPI.getMachineForSession) {
+ /* Get machine for the call to VBOX_SESSION_OPEN_EXISTING */
+ if (NS_FAILED(gVBoxAPI.UIVirtualBox.GetMachine(data->vboxObj, iid, machine)))
{
+ virReportError(VIR_ERR_NO_DOMAIN, "%s",
+ _("no domain with matching uuid"));
+ return -1;
+ }
+ }
+ return 0;
+}
+
static virDomainDefParserConfig vboxDomainDefParserConfig = {
.macPrefix = { 0x08, 0x00, 0x27 },
};
@@ -300,3 +344,54 @@ int vboxConnectClose(virConnectPtr conn)
return 0;
}
+
+int
+vboxDomainSave(virDomainPtr dom, const char *path ATTRIBUTE_UNUSED)
+{
+ VBOX_OBJECT_CHECK(dom->conn, int, -1);
+ IConsole *console = NULL;
+ vboxIIDUnion iid;
+ IMachine *machine = NULL;
+ IProgress *progress = NULL;
+ resultCodeUnion resultCode;
+ 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 */
+ if (openSessionForMachine(data, dom->uuid, &iid, &machine, true) < 0)
+ goto cleanup;
+
+ rc = gVBoxAPI.UISession.OpenExisting(data, &iid, machine);
+ if (NS_FAILED(rc))
+ goto cleanup;
+
+ rc = gVBoxAPI.UISession.GetConsole(data->vboxSession, &console);
+ if (NS_FAILED(rc) || !console)
+ goto freeSession;
+
+ rc = gVBoxAPI.UIConsole.SaveState(console, &progress);
+ if (!progress)
+ goto freeSession;
+
+ gVBoxAPI.UIProgress.WaitForCompletion(progress, -1);
+ gVBoxAPI.UIProgress.GetResultCode(progress, &resultCode);
+ if (RC_SUCCEEDED(resultCode))
+ ret = 0;
+
+ freeSession:
+ gVBoxAPI.UISession.Close(data->vboxSession);
+
+ cleanup:
+ DEBUGIID("UUID of machine being saved:", &iid);
+ VBOX_RELEASE(machine);
+ VBOX_RELEASE(console);
+ VBOX_RELEASE(progress);
+ vboxIIDUnalloc(&iid);
+ return ret;
+}
diff --git a/src/vbox/vbox_common.h b/src/vbox/vbox_common.h
index 61f410d..800e7cc 100644
--- a/src/vbox/vbox_common.h
+++ b/src/vbox/vbox_common.h
@@ -121,10 +121,51 @@ typedef PRUint32 nsresult;
# define NS_FAILED(_nsresult) (NS_UNLIKELY((_nsresult) & 0x80000000))
# define NS_SUCCEEDED(_nsresult) (NS_LIKELY(!((_nsresult) & 0x80000000)))
+/**
+ * An "interface id" which can be used to uniquely identify a given
+ * interface.
+ * A "unique identifier". This is modeled after OSF DCE UUIDs.
+ */
+
+struct nsID {
+ PRUint32 m0;
+ PRUint16 m1;
+ PRUint16 m2;
+ PRUint8 m3[8];
+};
+
+typedef struct nsID nsID;
+typedef nsID nsIID;
+
+typedef struct _vboxArray vboxArray;
+
+# ifdef WIN32
+
+struct _vboxArray {
+ void **items;
+ size_t count;
+ void *handle;
+};
+# define VBOX_ARRAY_INITIALIZER { NULL, 0, NULL }
+
+# else /* !WIN32 */
+
+struct _vboxArray {
+ void **items;
+ size_t count;
+};
+# define VBOX_ARRAY_INITIALIZER { NULL, 0 }
+
+# endif /* !WIN32 */
+
/* Simplied definitions in vbox_CAPI_*.h */
typedef void const *PCVBOXXPCOM;
-typedef void IVirtualBox;
-typedef void ISession;
+typedef struct nsISupports nsISupports;
+typedef nsISupports IVirtualBox;
+typedef nsISupports ISession;
+typedef nsISupports IConsole;
+typedef nsISupports IProgress;
+typedef nsISupports IMachine;
#endif /* VBOX_COMMON_H */
diff --git a/src/vbox/vbox_tmpl.c b/src/vbox/vbox_tmpl.c
index 6315a64..0e9b6c8 100644
--- a/src/vbox/vbox_tmpl.c
+++ b/src/vbox/vbox_tmpl.c
@@ -192,7 +192,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,\
@@ -355,12 +355,8 @@ 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 IID_MEMBER(name) (iidu->vboxIID_v2_x_WIN32.name)
static void
vboxIIDUnalloc_v2_x_WIN32(vboxGlobalData *data ATTRIBUTE_UNUSED,
@@ -370,12 +366,25 @@ vboxIIDUnalloc_v2_x_WIN32(vboxGlobalData *data ATTRIBUTE_UNUSED,
}
static void
+_vboxIIDUnalloc(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);
}
static void
+_vboxIIDToUUID(vboxGlobalData *data ATTRIBUTE_UNUSED, vboxIIDUnion *iidu, unsigned char
*uuid)
+{
+ vboxIIDToUUID_v2_x_WIN32(&iidu->vboxIID_v2_x_WIN32, uuid);
+}
+
+static void
vboxIIDFromUUID_v2_x_WIN32(vboxGlobalData *data, vboxIID_v2_x_WIN32 *iid,
const unsigned char *uuid)
{
@@ -384,12 +393,25 @@ vboxIIDFromUUID_v2_x_WIN32(vboxGlobalData *data, vboxIID_v2_x_WIN32
*iid,
nsIDFromChar((nsID *)&iid->value, uuid);
}
+static void
+_vboxIIDFromUUID(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)
{
return memcmp(&iid1->value, &iid2->value, sizeof(GUID)) == 0;
}
+static bool
+_vboxIIDIsEqual(vboxGlobalData *data ATTRIBUTE_UNUSED, vboxIIDUnion *iidu1, vboxIIDUnion
*iidu2)
+{
+ return vboxIIDIsEqual_v2_x_WIN32(&iidu1->vboxIID_v2_x_WIN32,
&iidu2->vboxIID_v2_x_WIN32);
+}
+
static void
vboxIIDFromArrayItem_v2_x_WIN32(vboxGlobalData *data, vboxIID_v2_x_WIN32 *iid,
vboxArray *array, int idx)
@@ -401,6 +423,13 @@ vboxIIDFromArrayItem_v2_x_WIN32(vboxGlobalData *data,
vboxIID_v2_x_WIN32 *iid,
memcpy(&iid->value, &items[idx], sizeof(GUID));
}
+static void
+_vboxIIDFromArrayItem(vboxGlobalData *data, vboxIIDUnion *iidu,
+ vboxArray *array, int idx)
+{
+ vboxIIDFromArrayItem_v2_x_WIN32(data, &iidu->vboxIID_v2_x_WIN32, array, idx);
+}
+
# 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)
@@ -414,17 +443,8 @@ vboxIIDFromArrayItem_v2_x_WIN32(vboxGlobalData *data,
vboxIID_v2_x_WIN32 *iid,
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 IID_MEMBER(name) (iidu->vboxIID_v2_x.name)
static void
vboxIIDUnalloc_v2_x(vboxGlobalData *data, vboxIID_v2_x *iid)
@@ -441,12 +461,25 @@ vboxIIDUnalloc_v2_x(vboxGlobalData *data, vboxIID_v2_x *iid)
}
static void
+_vboxIIDUnalloc(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);
}
static void
+_vboxIIDToUUID(vboxGlobalData *data ATTRIBUTE_UNUSED,
+ vboxIIDUnion *iidu, unsigned char *uuid)
+{
+ vboxIIDToUUID_v2_x(&iidu->vboxIID_v2_x, uuid);
+}
+
+static void
vboxIIDFromUUID_v2_x(vboxGlobalData *data, vboxIID_v2_x *iid,
const unsigned char *uuid)
{
@@ -458,12 +491,26 @@ vboxIIDFromUUID_v2_x(vboxGlobalData *data, vboxIID_v2_x *iid,
nsIDFromChar(iid->value, uuid);
}
+static void
+_vboxIIDFromUUID(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)
{
return memcmp(iid1->value, iid2->value, sizeof(nsID)) == 0;
}
+static bool
+_vboxIIDIsEqual(vboxGlobalData *data ATTRIBUTE_UNUSED,
+ vboxIIDUnion *iidu1, vboxIIDUnion *iidu2)
+{
+ return vboxIIDIsEqual_v2_x(&iidu1->vboxIID_v2_x,
&iidu2->vboxIID_v2_x);
+}
+
static void
vboxIIDFromArrayItem_v2_x(vboxGlobalData *data, vboxIID_v2_x *iid,
vboxArray *array, int idx)
@@ -475,6 +522,13 @@ vboxIIDFromArrayItem_v2_x(vboxGlobalData *data, vboxIID_v2_x *iid,
memcpy(iid->value, array->items[idx], sizeof(nsID));
}
+static void
+_vboxIIDFromArrayItem(vboxGlobalData *data, vboxIIDUnion *iidu,
+ vboxArray *array, int idx)
+{
+ vboxIIDFromArrayItem_v2_x(data, &iidu->vboxIID_v2_x, array, idx);
+}
+
# 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)
@@ -490,15 +544,8 @@ 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 IID_MEMBER(name) (iidu->vboxIID_v3_x.name)
static void
vboxIIDUnalloc_v3_x(vboxGlobalData *data, vboxIID_v3_x *iid)
@@ -512,6 +559,12 @@ vboxIIDUnalloc_v3_x(vboxGlobalData *data, vboxIID_v3_x *iid)
}
static void
+_vboxIIDUnalloc(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)
{
@@ -525,6 +578,13 @@ vboxIIDToUUID_v3_x(vboxGlobalData *data, vboxIID_v3_x *iid,
}
static void
+_vboxIIDToUUID(vboxGlobalData *data, vboxIIDUnion *iidu,
+ unsigned char *uuid)
+{
+ vboxIIDToUUID_v3_x(data, &iidu->vboxIID_v3_x, uuid);
+}
+
+static void
vboxIIDFromUUID_v3_x(vboxGlobalData *data, vboxIID_v3_x *iid,
const unsigned char *uuid)
{
@@ -537,6 +597,13 @@ vboxIIDFromUUID_v3_x(vboxGlobalData *data, vboxIID_v3_x *iid,
data->pFuncs->pfnUtf8ToUtf16(utf8, &iid->value);
}
+static void
+_vboxIIDFromUUID(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)
@@ -555,6 +622,12 @@ vboxIIDIsEqual_v3_x(vboxGlobalData *data, vboxIID_v3_x *iid1,
return memcmp(uuid1, uuid2, VIR_UUID_BUFLEN) == 0;
}
+static bool
+_vboxIIDIsEqual(vboxGlobalData *data, vboxIIDUnion *iidu1,
+ vboxIIDUnion *iidu2)
+{
+ return vboxIIDIsEqual_v3_x(data, &iidu1->vboxIID_v3_x,
&iidu2->vboxIID_v3_x);
+}
static void
vboxIIDFromArrayItem_v3_x(vboxGlobalData *data, vboxIID_v3_x *iid,
@@ -566,6 +639,13 @@ vboxIIDFromArrayItem_v3_x(vboxGlobalData *data, vboxIID_v3_x *iid,
iid->owner = false;
}
+static void
+_vboxIIDFromArrayItem(vboxGlobalData *data, vboxIIDUnion *iidu,
+ vboxArray *array, int idx)
+{
+ vboxIIDFromArrayItem_v3_x(data, &iidu->vboxIID_v3_x, array, idx);
+}
+
# define vboxIIDUnalloc(iid) vboxIIDUnalloc_v3_x(data, iid)
# define vboxIIDToUUID(iid, uuid) vboxIIDToUUID_v3_x(data, iid, uuid)
@@ -1826,67 +1906,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)
@@ -11303,12 +11322,124 @@ static int _pfnUtf8ToUtf16(PCVBOXXPCOM pFuncs, const char
*pszString, PRUnichar
return pFuncs->pfnUtf8ToUtf16(pszString, ppwszString);
}
+#if VBOX_API_VERSION == 2002000
+
+static void _vboxIIDInitialize(vboxIIDUnion *iidu)
+{
+ memset(iidu, 0, sizeof(vboxIIDUnion));
+}
+
+static void _DEBUGIID(const char *msg, vboxIIDUnion *iidu)
+{
+# ifdef WIN32
+ DEBUGUUID(msg, (nsID *)&IID_MEMBER(value));
+# else /* !WIN32 */
+ DEBUGUUID(msg, IID_MEMBER(value));
+# endif /* !WIN32 */
+}
+
+#else /* VBOX_API_VERSION != 2002000 */
+
+static void _vboxIIDInitialize(vboxIIDUnion *iidu)
+{
+ memset(iidu, 0, sizeof(vboxIIDUnion));
+ IID_MEMBER(owner) = true;
+}
+
+static void _DEBUGIID(const char *msg, vboxIIDUnion *iidu)
+{
+ DEBUGPRUnichar(msg, IID_MEMBER(value));
+}
+
+#endif /* VBOX_API_VERSION != 2002000 */
+
+static nsresult _nsisupportsRelease(nsISupports *nsi)
+{
+ return nsi->vtbl->Release(nsi);
+}
+
static nsresult
_virtualboxGetVersion(IVirtualBox *vboxObj, PRUnichar **versionUtf16)
{
return vboxObj->vtbl->GetVersion(vboxObj, versionUtf16);
}
+#if VBOX_API_VERSION < 4000000
+
+static nsresult
+_virtualboxGetMachine(IVirtualBox *vboxObj, vboxIIDUnion *iidu, IMachine **machine)
+{
+ return vboxObj->vtbl->GetMachine(vboxObj, IID_MEMBER(value), machine);
+}
+
+#else /* VBOX_API_VERSION >= 4000000 */
+
+static nsresult
+_virtualboxGetMachine(IVirtualBox *vboxObj, vboxIIDUnion *iidu, IMachine **machine)
+{
+ return vboxObj->vtbl->FindMachine(vboxObj, IID_MEMBER(value), machine);
+}
+
+#endif /* VBOX_API_VERSION >= 4000000 */
+
+#if VBOX_API_VERSION < 4000000
+
+static nsresult
+_sessionOpenExisting(vboxGlobalData *data, vboxIIDUnion *iidu, IMachine *machine
ATTRIBUTE_UNUSED)
+{
+ return data->vboxObj->vtbl->OpenExistingSession(data->vboxObj,
data->vboxSession, IID_MEMBER(value));
+}
+
+static nsresult
+_sessionClose(ISession *session)
+{
+ return session->vtbl->Close(session);
+}
+
+#else /* VBOX_API_VERSION >= 4000000 */
+
+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 */
+
+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
+_progressGetResultCode(IProgress *progress, resultCodeUnion *resultCode)
+{
+#if VBOX_API_VERSION == 2002000
+ return progress->vtbl->GetResultCode(progress,
&resultCode->uResultCode);
+#else /* VBOX_API_VERSION != 2002000 */
+ return progress->vtbl->GetResultCode(progress,
&resultCode->resultCode);
+#endif /* VBOX_API_VERSION != 2002000 */
+}
+
static vboxUniformedPFN _UPFN = {
.Initialize = _pfnInitialize,
.Uninitialize = _pfnUninitialize,
@@ -11319,8 +11450,38 @@ static vboxUniformedPFN _UPFN = {
.Utf8ToUtf16 = _pfnUtf8ToUtf16,
};
+static vboxUniformedIID _UIID = {
+ .vboxIIDInitialize = _vboxIIDInitialize,
+ .vboxIIDUnalloc = _vboxIIDUnalloc,
+ .vboxIIDToUUID = _vboxIIDToUUID,
+ .vboxIIDFromUUID = _vboxIIDFromUUID,
+ .vboxIIDIsEqual = _vboxIIDIsEqual,
+ .vboxIIDFromArrayItem = _vboxIIDFromArrayItem,
+ .DEBUGIID = _DEBUGIID,
+};
+
+static vboxUniformednsISupports _nsUISupports = {
+ .Release = _nsisupportsRelease,
+};
+
static vboxUniformedIVirtualBox _UIVirtualBox = {
.GetVersion = _virtualboxGetVersion,
+ .GetMachine = _virtualboxGetMachine,
+};
+
+static vboxUniformedISession _UISession = {
+ .OpenExisting = _sessionOpenExisting,
+ .GetConsole = _sessionGetConsole,
+ .Close = _sessionClose,
+};
+
+static vboxUniformedIConsole _UIConsole = {
+ .SaveState = _consoleSaveState,
+};
+
+static vboxUniformedIProgress _UIProgress = {
+ .WaitForCompletion = _progressWaitForCompletion,
+ .GetResultCode = _progressGetResultCode,
};
void NAME(InstallUniformedAPI)(vboxUniformedAPI *pVBoxAPI)
@@ -11330,7 +11491,12 @@ void NAME(InstallUniformedAPI)(vboxUniformedAPI *pVBoxAPI)
pVBoxAPI->initializeDomainEvent = _initializeDomainEvent;
pVBoxAPI->registerGlobalData = _registerGlobalData;
pVBoxAPI->UPFN = _UPFN;
+ pVBoxAPI->UIID = _UIID;
+ pVBoxAPI->nsUISupports = _nsUISupports;
pVBoxAPI->UIVirtualBox = _UIVirtualBox;
+ pVBoxAPI->UISession = _UISession;
+ pVBoxAPI->UIConsole = _UIConsole;
+ pVBoxAPI->UIProgress = _UIProgress;
#if VBOX_API_VERSION <= 2002000 || VBOX_API_VERSION >= 4000000
pVBoxAPI->domainEventCallbacks = 0;
@@ -11344,6 +11510,12 @@ void NAME(InstallUniformedAPI)(vboxUniformedAPI *pVBoxAPI)
pVBoxAPI->hasStaticGlobalData = 1;
#endif /* VBOX_API_VERSION > 2002000 */
+#if VBOX_API_VERSION >= 4000000
+ /* Get machine for the call to VBOX_SESSION_OPEN_EXISTING */
+ pVBoxAPI->getMachineForSession = 1;
+#else /* VBOX_API_VERSION < 4000000 */
+ pVBoxAPI->getMachineForSession = 0;
+#endif /* VBOX_API_VERSION < 4000000 */
}
/**
diff --git a/src/vbox/vbox_uniformed_api.h b/src/vbox/vbox_uniformed_api.h
index f424047..8538754 100644
--- a/src/vbox/vbox_uniformed_api.h
+++ b/src/vbox/vbox_uniformed_api.h
@@ -56,6 +56,46 @@
*
*/
+/* Extracted define from vbox_tmpl.c */
+
+# ifdef WIN32
+struct _vboxIID_v2_x_WIN32 {
+ /* IID is represented by a GUID value. */
+ GUID value;
+};
+# endif /* !WIN32 */
+
+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;
+};
+
+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;
+};
+
+typedef union {
+# ifdef WIN32
+ struct _vboxIID_v2_x_WIN32 vboxIID_v2_x_WIN32;
+# endif /* !WIN32 */
+ struct _vboxIID_v2_x vboxIID_v2_x;
+ struct _vboxIID_v3_x vboxIID_v3_x;
+} vboxIIDUnion;
+
+typedef union {
+ nsresult uResultCode;
+ PRInt32 resultCode;
+} resultCodeUnion;
+
typedef struct {
virMutex lock;
unsigned long version;
@@ -111,11 +151,46 @@ typedef struct {
int (*Utf8ToUtf16)(PCVBOXXPCOM pFuncs, const char *pszString, PRUnichar
**ppwszString);
} vboxUniformedPFN;
+/* Functions for vboxIID */
+typedef struct {
+ void (*vboxIIDInitialize)(vboxIIDUnion *iidu);
+ void (*vboxIIDUnalloc)(vboxGlobalData *data, vboxIIDUnion *iidu);
+ void (*vboxIIDToUUID)(vboxGlobalData *data, vboxIIDUnion *iidu, unsigned char
*uuid);
+ void (*vboxIIDFromUUID)(vboxGlobalData *data, vboxIIDUnion *iidu, const unsigned char
*uuid);
+ bool (*vboxIIDIsEqual)(vboxGlobalData *data, vboxIIDUnion *iidu1, vboxIIDUnion
*iidu2);
+ void (*vboxIIDFromArrayItem)(vboxGlobalData *data, vboxIIDUnion *iidu, vboxArray
*array, int idx);
+ void (*DEBUGIID)(const char *msg, vboxIIDUnion *iidu);
+} vboxUniformedIID;
+
+/* Functions for nsISupports */
+typedef struct {
+ nsresult (*Release)(nsISupports *nsi);
+} vboxUniformednsISupports;
+
/* Functions for IVirtualBox */
typedef struct {
nsresult (*GetVersion)(IVirtualBox *vboxObj, PRUnichar **versionUtf16);
+ nsresult (*GetMachine)(IVirtualBox *vboxObj, vboxIIDUnion *iidu, IMachine
**machine);
} vboxUniformedIVirtualBox;
+/* Functions for ISession */
+typedef struct {
+ nsresult (*OpenExisting)(vboxGlobalData *data, vboxIIDUnion *iidu, IMachine
*machine);
+ nsresult (*GetConsole)(ISession *session, IConsole **console);
+ nsresult (*Close)(ISession *session);
+} vboxUniformedISession;
+
+/* Functions for IConsole */
+typedef struct {
+ nsresult (*SaveState)(IConsole *console, IProgress **progress);
+} vboxUniformedIConsole;
+
+/* Functions for IProgress */
+typedef struct {
+ nsresult (*WaitForCompletion)(IProgress *progress, PRInt32 timeout);
+ nsresult (*GetResultCode)(IProgress *progress, resultCodeUnion *resultCode);
+} vboxUniformedIProgress;
+
typedef struct {
/* vbox API version */
uint32_t APIVersion;
@@ -124,10 +199,16 @@ typedef struct {
int (*initializeDomainEvent)(vboxGlobalData *data);
void (*registerGlobalData)(vboxGlobalData *data);
vboxUniformedPFN UPFN;
+ vboxUniformedIID UIID;
+ vboxUniformednsISupports nsUISupports;
vboxUniformedIVirtualBox UIVirtualBox;
+ vboxUniformedISession UISession;
+ vboxUniformedIConsole UIConsole;
+ vboxUniformedIProgress UIProgress;
/* vbox API features */
bool domainEventCallbacks;
bool hasStaticGlobalData;
+ bool getMachineForSession;
} vboxUniformedAPI;
/* libvirt API
@@ -138,6 +219,7 @@ virDrvOpenStatus vboxConnectOpen(virConnectPtr conn,
virConnectAuthPtr auth,
unsigned int flags);
int vboxConnectClose(virConnectPtr conn);
+int vboxDomainSave(virDomainPtr dom, const char *path);
/* Version specified functions for installing uniformed API */
void vbox22InstallUniformedAPI(vboxUniformedAPI *pVBoxAPI);
--
1.7.9.5