[libvirt] [PATCH 03/66] vbox: Rewrite vboxDomainSave

Taowei uaedante at gmail.com
Mon Aug 11 10:06:06 UTC 2014


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




More information about the libvir-list mailing list