mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-23 14:15:28 +00:00
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.
This commit is contained in:
parent
c6084f19d0
commit
7e052265c9
@ -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;
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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,
|
||||
@ -369,12 +365,25 @@ vboxIIDUnalloc_v2_x_WIN32(vboxGlobalData *data ATTRIBUTE_UNUSED,
|
||||
/* Nothing to free */
|
||||
}
|
||||
|
||||
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)
|
||||
@ -440,12 +460,25 @@ vboxIIDUnalloc_v2_x(vboxGlobalData *data, vboxIID_v2_x *iid)
|
||||
iid->value = NULL;
|
||||
}
|
||||
|
||||
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)
|
||||
@ -511,6 +558,12 @@ vboxIIDUnalloc_v3_x(vboxGlobalData *data, vboxIID_v3_x *iid)
|
||||
iid->owner = true;
|
||||
}
|
||||
|
||||
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)
|
||||
@ -524,6 +577,13 @@ vboxIIDToUUID_v3_x(vboxGlobalData *data, vboxIID_v3_x *iid,
|
||||
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
|
||||
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 */
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user