提交 7e052265 编写于 作者: T Taowei 提交者: Michal Privoznik

vbox: Rewrite vboxDomainSave

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.
上级 c6084f19
...@@ -42,6 +42,9 @@ ...@@ -42,6 +42,9 @@
VIR_LOG_INIT("vbox.vbox_common"); 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) \ #define VBOX_UTF16_FREE(arg) \
do { \ do { \
if (arg) { \ if (arg) { \
...@@ -69,6 +72,31 @@ VIR_LOG_INIT("vbox.vbox_common"); ...@@ -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_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_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. */ /* global vbox API, used for all common codes. */
static vboxUniformedAPI gVBoxAPI; static vboxUniformedAPI gVBoxAPI;
...@@ -103,6 +131,22 @@ int vboxRegisterUniformedAPI(uint32_t uVersion) ...@@ -103,6 +131,22 @@ int vboxRegisterUniformedAPI(uint32_t uVersion)
return 0; 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 = { static virDomainDefParserConfig vboxDomainDefParserConfig = {
.macPrefix = { 0x08, 0x00, 0x27 }, .macPrefix = { 0x08, 0x00, 0x27 },
}; };
...@@ -300,3 +344,54 @@ int vboxConnectClose(virConnectPtr conn) ...@@ -300,3 +344,54 @@ int vboxConnectClose(virConnectPtr conn)
return 0; 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;
}
...@@ -121,10 +121,51 @@ typedef PRUint32 nsresult; ...@@ -121,10 +121,51 @@ typedef PRUint32 nsresult;
# define NS_FAILED(_nsresult) (NS_UNLIKELY((_nsresult) & 0x80000000)) # define NS_FAILED(_nsresult) (NS_UNLIKELY((_nsresult) & 0x80000000))
# define NS_SUCCEEDED(_nsresult) (NS_LIKELY(!((_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 */ /* Simplied definitions in vbox_CAPI_*.h */
typedef void const *PCVBOXXPCOM; typedef void const *PCVBOXXPCOM;
typedef void IVirtualBox; typedef struct nsISupports nsISupports;
typedef void ISession; typedef nsISupports IVirtualBox;
typedef nsISupports ISession;
typedef nsISupports IConsole;
typedef nsISupports IProgress;
typedef nsISupports IMachine;
#endif /* VBOX_COMMON_H */ #endif /* VBOX_COMMON_H */
...@@ -192,7 +192,7 @@ if (strUtf16) {\ ...@@ -192,7 +192,7 @@ if (strUtf16) {\
#define DEBUGUUID(msg, iid) \ #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)->m0,\
(unsigned)(iid)->m1,\ (unsigned)(iid)->m1,\
(unsigned)(iid)->m2,\ (unsigned)(iid)->m2,\
...@@ -355,12 +355,8 @@ static void nsIDFromChar(nsID *iid, const unsigned char *uuid) ...@@ -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;
typedef struct _vboxIID_v2_x_WIN32 vboxIID_v2_x_WIN32; 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 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 static void
vboxIIDUnalloc_v2_x_WIN32(vboxGlobalData *data ATTRIBUTE_UNUSED, vboxIIDUnalloc_v2_x_WIN32(vboxGlobalData *data ATTRIBUTE_UNUSED,
...@@ -369,12 +365,25 @@ vboxIIDUnalloc_v2_x_WIN32(vboxGlobalData *data ATTRIBUTE_UNUSED, ...@@ -369,12 +365,25 @@ vboxIIDUnalloc_v2_x_WIN32(vboxGlobalData *data ATTRIBUTE_UNUSED,
/* Nothing to free */ /* Nothing to free */
} }
static void
_vboxIIDUnalloc(vboxGlobalData *data ATTRIBUTE_UNUSED,
vboxIIDUnion *iid ATTRIBUTE_UNUSED)
{
/* Nothing to free */
}
static void static void
vboxIIDToUUID_v2_x_WIN32(vboxIID_v2_x_WIN32 *iid, unsigned char *uuid) vboxIIDToUUID_v2_x_WIN32(vboxIID_v2_x_WIN32 *iid, unsigned char *uuid)
{ {
nsIDtoChar(uuid, (nsID *)&iid->value); 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 static void
vboxIIDFromUUID_v2_x_WIN32(vboxGlobalData *data, vboxIID_v2_x_WIN32 *iid, vboxIIDFromUUID_v2_x_WIN32(vboxGlobalData *data, vboxIID_v2_x_WIN32 *iid,
const unsigned char *uuid) const unsigned char *uuid)
...@@ -384,12 +393,25 @@ vboxIIDFromUUID_v2_x_WIN32(vboxGlobalData *data, vboxIID_v2_x_WIN32 *iid, ...@@ -384,12 +393,25 @@ vboxIIDFromUUID_v2_x_WIN32(vboxGlobalData *data, vboxIID_v2_x_WIN32 *iid,
nsIDFromChar((nsID *)&iid->value, uuid); 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 static bool
vboxIIDIsEqual_v2_x_WIN32(vboxIID_v2_x_WIN32 *iid1, vboxIID_v2_x_WIN32 *iid2) vboxIIDIsEqual_v2_x_WIN32(vboxIID_v2_x_WIN32 *iid1, vboxIID_v2_x_WIN32 *iid2)
{ {
return memcmp(&iid1->value, &iid2->value, sizeof(GUID)) == 0; 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 static void
vboxIIDFromArrayItem_v2_x_WIN32(vboxGlobalData *data, vboxIID_v2_x_WIN32 *iid, vboxIIDFromArrayItem_v2_x_WIN32(vboxGlobalData *data, vboxIID_v2_x_WIN32 *iid,
vboxArray *array, int idx) vboxArray *array, int idx)
...@@ -401,6 +423,13 @@ vboxIIDFromArrayItem_v2_x_WIN32(vboxGlobalData *data, vboxIID_v2_x_WIN32 *iid, ...@@ -401,6 +423,13 @@ vboxIIDFromArrayItem_v2_x_WIN32(vboxGlobalData *data, vboxIID_v2_x_WIN32 *iid,
memcpy(&iid->value, &items[idx], sizeof(GUID)); 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 vboxIIDUnalloc(iid) vboxIIDUnalloc_v2_x_WIN32(data, iid)
# define vboxIIDToUUID(iid, uuid) vboxIIDToUUID_v2_x_WIN32(iid, uuid) # define vboxIIDToUUID(iid, uuid) vboxIIDToUUID_v2_x_WIN32(iid, uuid)
# define vboxIIDFromUUID(iid, uuid) vboxIIDFromUUID_v2_x_WIN32(data, 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, ...@@ -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;
typedef struct _vboxIID_v2_x vboxIID_v2_x; 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 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 static void
vboxIIDUnalloc_v2_x(vboxGlobalData *data, vboxIID_v2_x *iid) vboxIIDUnalloc_v2_x(vboxGlobalData *data, vboxIID_v2_x *iid)
...@@ -440,12 +460,25 @@ vboxIIDUnalloc_v2_x(vboxGlobalData *data, vboxIID_v2_x *iid) ...@@ -440,12 +460,25 @@ vboxIIDUnalloc_v2_x(vboxGlobalData *data, vboxIID_v2_x *iid)
iid->value = NULL; iid->value = NULL;
} }
static void
_vboxIIDUnalloc(vboxGlobalData *data, vboxIIDUnion *iidu)
{
vboxIIDUnalloc_v2_x(data, &iidu->vboxIID_v2_x);
}
static void static void
vboxIIDToUUID_v2_x(vboxIID_v2_x *iid, unsigned char *uuid) vboxIIDToUUID_v2_x(vboxIID_v2_x *iid, unsigned char *uuid)
{ {
nsIDtoChar(uuid, iid->value); 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 static void
vboxIIDFromUUID_v2_x(vboxGlobalData *data, vboxIID_v2_x *iid, vboxIIDFromUUID_v2_x(vboxGlobalData *data, vboxIID_v2_x *iid,
const unsigned char *uuid) const unsigned char *uuid)
...@@ -458,12 +491,26 @@ vboxIIDFromUUID_v2_x(vboxGlobalData *data, vboxIID_v2_x *iid, ...@@ -458,12 +491,26 @@ vboxIIDFromUUID_v2_x(vboxGlobalData *data, vboxIID_v2_x *iid,
nsIDFromChar(iid->value, uuid); 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 static bool
vboxIIDIsEqual_v2_x(vboxIID_v2_x *iid1, vboxIID_v2_x *iid2) vboxIIDIsEqual_v2_x(vboxIID_v2_x *iid1, vboxIID_v2_x *iid2)
{ {
return memcmp(iid1->value, iid2->value, sizeof(nsID)) == 0; 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 static void
vboxIIDFromArrayItem_v2_x(vboxGlobalData *data, vboxIID_v2_x *iid, vboxIIDFromArrayItem_v2_x(vboxGlobalData *data, vboxIID_v2_x *iid,
vboxArray *array, int idx) vboxArray *array, int idx)
...@@ -475,6 +522,13 @@ vboxIIDFromArrayItem_v2_x(vboxGlobalData *data, vboxIID_v2_x *iid, ...@@ -475,6 +522,13 @@ vboxIIDFromArrayItem_v2_x(vboxGlobalData *data, vboxIID_v2_x *iid,
memcpy(iid->value, array->items[idx], sizeof(nsID)); 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 vboxIIDUnalloc(iid) vboxIIDUnalloc_v2_x(data, iid)
# define vboxIIDToUUID(iid, uuid) vboxIIDToUUID_v2_x(iid, uuid) # define vboxIIDToUUID(iid, uuid) vboxIIDToUUID_v2_x(iid, uuid)
# define vboxIIDFromUUID(iid, uuid) vboxIIDFromUUID_v2_x(data, 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, ...@@ -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;
typedef struct _vboxIID_v3_x vboxIID_v3_x; 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 VBOX_IID_INITIALIZER { NULL, true }
# define IID_MEMBER(name) (iidu->vboxIID_v3_x.name)
static void static void
vboxIIDUnalloc_v3_x(vboxGlobalData *data, vboxIID_v3_x *iid) vboxIIDUnalloc_v3_x(vboxGlobalData *data, vboxIID_v3_x *iid)
...@@ -511,6 +558,12 @@ vboxIIDUnalloc_v3_x(vboxGlobalData *data, vboxIID_v3_x *iid) ...@@ -511,6 +558,12 @@ vboxIIDUnalloc_v3_x(vboxGlobalData *data, vboxIID_v3_x *iid)
iid->owner = true; iid->owner = true;
} }
static void
_vboxIIDUnalloc(vboxGlobalData *data, vboxIIDUnion *iidu)
{
vboxIIDUnalloc_v3_x(data, &iidu->vboxIID_v3_x);
}
static void static void
vboxIIDToUUID_v3_x(vboxGlobalData *data, vboxIID_v3_x *iid, vboxIIDToUUID_v3_x(vboxGlobalData *data, vboxIID_v3_x *iid,
unsigned char *uuid) unsigned char *uuid)
...@@ -524,6 +577,13 @@ vboxIIDToUUID_v3_x(vboxGlobalData *data, vboxIID_v3_x *iid, ...@@ -524,6 +577,13 @@ vboxIIDToUUID_v3_x(vboxGlobalData *data, vboxIID_v3_x *iid,
data->pFuncs->pfnUtf8Free(utf8); data->pFuncs->pfnUtf8Free(utf8);
} }
static void
_vboxIIDToUUID(vboxGlobalData *data, vboxIIDUnion *iidu,
unsigned char *uuid)
{
vboxIIDToUUID_v3_x(data, &iidu->vboxIID_v3_x, uuid);
}
static void static void
vboxIIDFromUUID_v3_x(vboxGlobalData *data, vboxIID_v3_x *iid, vboxIIDFromUUID_v3_x(vboxGlobalData *data, vboxIID_v3_x *iid,
const unsigned char *uuid) const unsigned char *uuid)
...@@ -537,6 +597,13 @@ vboxIIDFromUUID_v3_x(vboxGlobalData *data, vboxIID_v3_x *iid, ...@@ -537,6 +597,13 @@ vboxIIDFromUUID_v3_x(vboxGlobalData *data, vboxIID_v3_x *iid,
data->pFuncs->pfnUtf8ToUtf16(utf8, &iid->value); 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 static bool
vboxIIDIsEqual_v3_x(vboxGlobalData *data, vboxIID_v3_x *iid1, vboxIIDIsEqual_v3_x(vboxGlobalData *data, vboxIID_v3_x *iid1,
vboxIID_v3_x *iid2) vboxIID_v3_x *iid2)
...@@ -555,6 +622,12 @@ vboxIIDIsEqual_v3_x(vboxGlobalData *data, vboxIID_v3_x *iid1, ...@@ -555,6 +622,12 @@ vboxIIDIsEqual_v3_x(vboxGlobalData *data, vboxIID_v3_x *iid1,
return memcmp(uuid1, uuid2, VIR_UUID_BUFLEN) == 0; 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 static void
vboxIIDFromArrayItem_v3_x(vboxGlobalData *data, vboxIID_v3_x *iid, vboxIIDFromArrayItem_v3_x(vboxGlobalData *data, vboxIID_v3_x *iid,
...@@ -566,6 +639,13 @@ 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; 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 vboxIIDUnalloc(iid) vboxIIDUnalloc_v3_x(data, iid)
# define vboxIIDToUUID(iid, uuid) vboxIIDToUUID_v3_x(data, iid, uuid) # define vboxIIDToUUID(iid, uuid) vboxIIDToUUID_v3_x(data, iid, uuid)
...@@ -1826,67 +1906,6 @@ vboxDomainGetState(virDomainPtr dom, ...@@ -1826,67 +1906,6 @@ vboxDomainGetState(virDomainPtr dom,
return ret; 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 static int
vboxDomainSetVcpusFlags(virDomainPtr dom, unsigned int nvcpus, vboxDomainSetVcpusFlags(virDomainPtr dom, unsigned int nvcpus,
unsigned int flags) unsigned int flags)
...@@ -11303,12 +11322,124 @@ static int _pfnUtf8ToUtf16(PCVBOXXPCOM pFuncs, const char *pszString, PRUnichar ...@@ -11303,12 +11322,124 @@ static int _pfnUtf8ToUtf16(PCVBOXXPCOM pFuncs, const char *pszString, PRUnichar
return pFuncs->pfnUtf8ToUtf16(pszString, ppwszString); 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 static nsresult
_virtualboxGetVersion(IVirtualBox *vboxObj, PRUnichar **versionUtf16) _virtualboxGetVersion(IVirtualBox *vboxObj, PRUnichar **versionUtf16)
{ {
return vboxObj->vtbl->GetVersion(vboxObj, 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 = { static vboxUniformedPFN _UPFN = {
.Initialize = _pfnInitialize, .Initialize = _pfnInitialize,
.Uninitialize = _pfnUninitialize, .Uninitialize = _pfnUninitialize,
...@@ -11319,8 +11450,38 @@ static vboxUniformedPFN _UPFN = { ...@@ -11319,8 +11450,38 @@ static vboxUniformedPFN _UPFN = {
.Utf8ToUtf16 = _pfnUtf8ToUtf16, .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 = { static vboxUniformedIVirtualBox _UIVirtualBox = {
.GetVersion = _virtualboxGetVersion, .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) void NAME(InstallUniformedAPI)(vboxUniformedAPI *pVBoxAPI)
...@@ -11330,7 +11491,12 @@ void NAME(InstallUniformedAPI)(vboxUniformedAPI *pVBoxAPI) ...@@ -11330,7 +11491,12 @@ void NAME(InstallUniformedAPI)(vboxUniformedAPI *pVBoxAPI)
pVBoxAPI->initializeDomainEvent = _initializeDomainEvent; pVBoxAPI->initializeDomainEvent = _initializeDomainEvent;
pVBoxAPI->registerGlobalData = _registerGlobalData; pVBoxAPI->registerGlobalData = _registerGlobalData;
pVBoxAPI->UPFN = _UPFN; pVBoxAPI->UPFN = _UPFN;
pVBoxAPI->UIID = _UIID;
pVBoxAPI->nsUISupports = _nsUISupports;
pVBoxAPI->UIVirtualBox = _UIVirtualBox; pVBoxAPI->UIVirtualBox = _UIVirtualBox;
pVBoxAPI->UISession = _UISession;
pVBoxAPI->UIConsole = _UIConsole;
pVBoxAPI->UIProgress = _UIProgress;
#if VBOX_API_VERSION <= 2002000 || VBOX_API_VERSION >= 4000000 #if VBOX_API_VERSION <= 2002000 || VBOX_API_VERSION >= 4000000
pVBoxAPI->domainEventCallbacks = 0; pVBoxAPI->domainEventCallbacks = 0;
...@@ -11344,6 +11510,12 @@ void NAME(InstallUniformedAPI)(vboxUniformedAPI *pVBoxAPI) ...@@ -11344,6 +11510,12 @@ void NAME(InstallUniformedAPI)(vboxUniformedAPI *pVBoxAPI)
pVBoxAPI->hasStaticGlobalData = 1; pVBoxAPI->hasStaticGlobalData = 1;
#endif /* VBOX_API_VERSION > 2002000 */ #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 */
} }
/** /**
......
...@@ -56,6 +56,46 @@ ...@@ -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 { typedef struct {
virMutex lock; virMutex lock;
unsigned long version; unsigned long version;
...@@ -111,11 +151,46 @@ typedef struct { ...@@ -111,11 +151,46 @@ typedef struct {
int (*Utf8ToUtf16)(PCVBOXXPCOM pFuncs, const char *pszString, PRUnichar **ppwszString); int (*Utf8ToUtf16)(PCVBOXXPCOM pFuncs, const char *pszString, PRUnichar **ppwszString);
} vboxUniformedPFN; } 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 */ /* Functions for IVirtualBox */
typedef struct { typedef struct {
nsresult (*GetVersion)(IVirtualBox *vboxObj, PRUnichar **versionUtf16); nsresult (*GetVersion)(IVirtualBox *vboxObj, PRUnichar **versionUtf16);
nsresult (*GetMachine)(IVirtualBox *vboxObj, vboxIIDUnion *iidu, IMachine **machine);
} vboxUniformedIVirtualBox; } 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 { typedef struct {
/* vbox API version */ /* vbox API version */
uint32_t APIVersion; uint32_t APIVersion;
...@@ -124,10 +199,16 @@ typedef struct { ...@@ -124,10 +199,16 @@ typedef struct {
int (*initializeDomainEvent)(vboxGlobalData *data); int (*initializeDomainEvent)(vboxGlobalData *data);
void (*registerGlobalData)(vboxGlobalData *data); void (*registerGlobalData)(vboxGlobalData *data);
vboxUniformedPFN UPFN; vboxUniformedPFN UPFN;
vboxUniformedIID UIID;
vboxUniformednsISupports nsUISupports;
vboxUniformedIVirtualBox UIVirtualBox; vboxUniformedIVirtualBox UIVirtualBox;
vboxUniformedISession UISession;
vboxUniformedIConsole UIConsole;
vboxUniformedIProgress UIProgress;
/* vbox API features */ /* vbox API features */
bool domainEventCallbacks; bool domainEventCallbacks;
bool hasStaticGlobalData; bool hasStaticGlobalData;
bool getMachineForSession;
} vboxUniformedAPI; } vboxUniformedAPI;
/* libvirt API /* libvirt API
...@@ -138,6 +219,7 @@ virDrvOpenStatus vboxConnectOpen(virConnectPtr conn, ...@@ -138,6 +219,7 @@ virDrvOpenStatus vboxConnectOpen(virConnectPtr conn,
virConnectAuthPtr auth, virConnectAuthPtr auth,
unsigned int flags); unsigned int flags);
int vboxConnectClose(virConnectPtr conn); int vboxConnectClose(virConnectPtr conn);
int vboxDomainSave(virDomainPtr dom, const char *path);
/* Version specified functions for installing uniformed API */ /* Version specified functions for installing uniformed API */
void vbox22InstallUniformedAPI(vboxUniformedAPI *pVBoxAPI); void vbox22InstallUniformedAPI(vboxUniformedAPI *pVBoxAPI);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册