mirror of
https://github.com/libvirt/libvirt.git
synced 2025-02-25 18:55:26 -06:00
vbox: Handle different array representations of XPCOM and MSCOM
Add a vboxArray to hide the details from the general driver code.
This commit is contained in:
parent
448347f8b0
commit
d5b1933e56
@ -646,3 +646,110 @@ void
|
|||||||
VBoxCGlueTerm(void)
|
VBoxCGlueTerm(void)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* In MSCOM an array is represented by a SAFEARRAY pointer. To access the items
|
||||||
|
* in the array the SafeArrayAccessData function is used to lock the array and
|
||||||
|
* get its contents. When the items aren't needed anymore the
|
||||||
|
* SafeArrayUnaccessData function is used to unlock the array. The pointer
|
||||||
|
* retuned by SafeArrayAccessData function becomes invalid. Finally the
|
||||||
|
* SafeArrayDestroy function is called to destroy the array, it also releases
|
||||||
|
* or frees all items in the array according to their type.
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef HRESULT __stdcall (*SafeArrayGetter)(void *self, SAFEARRAY **array);
|
||||||
|
typedef HRESULT __stdcall (*SafeArrayGetterWithArg)(void *self, void *arg, SAFEARRAY **array);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Call the getter with self as first argument and fill the array with the
|
||||||
|
* returned items.
|
||||||
|
*/
|
||||||
|
nsresult
|
||||||
|
vboxArrayGet(vboxArray *array, void *self, void *getter)
|
||||||
|
{
|
||||||
|
HRESULT hrc;
|
||||||
|
SAFEARRAY *safeArray = NULL;
|
||||||
|
void **items = NULL;
|
||||||
|
|
||||||
|
array->items = NULL;
|
||||||
|
array->count = 0;
|
||||||
|
array->handle = NULL;
|
||||||
|
|
||||||
|
hrc = ((SafeArrayGetter)getter)(self, &safeArray);
|
||||||
|
|
||||||
|
if (FAILED(hrc)) {
|
||||||
|
return hrc;
|
||||||
|
}
|
||||||
|
|
||||||
|
hrc = SafeArrayAccessData(safeArray, (void **)&items);
|
||||||
|
|
||||||
|
if (FAILED(hrc)) {
|
||||||
|
SafeArrayDestroy(safeArray);
|
||||||
|
return hrc;
|
||||||
|
}
|
||||||
|
|
||||||
|
array->items = items;
|
||||||
|
array->count = safeArray->rgsabound[0].cElements;
|
||||||
|
array->handle = safeArray;
|
||||||
|
|
||||||
|
return hrc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Call the getter with self as first argument and arg as second argument
|
||||||
|
* and fill the array with the returned items.
|
||||||
|
*/
|
||||||
|
nsresult
|
||||||
|
vboxArrayGetWithArg(vboxArray *array, void *self, void *getter, void *arg)
|
||||||
|
{
|
||||||
|
HRESULT hrc;
|
||||||
|
SAFEARRAY *safeArray = NULL;
|
||||||
|
void **items = NULL;
|
||||||
|
|
||||||
|
array->items = NULL;
|
||||||
|
array->count = 0;
|
||||||
|
array->handle = NULL;
|
||||||
|
|
||||||
|
hrc = ((SafeArrayGetterWithArg)getter)(self, arg, &safeArray);
|
||||||
|
|
||||||
|
if (FAILED(hrc)) {
|
||||||
|
return hrc;
|
||||||
|
}
|
||||||
|
|
||||||
|
hrc = SafeArrayAccessData(safeArray, (void **)&items);
|
||||||
|
|
||||||
|
if (FAILED(hrc)) {
|
||||||
|
SafeArrayDestroy(safeArray);
|
||||||
|
return hrc;
|
||||||
|
}
|
||||||
|
|
||||||
|
array->items = items;
|
||||||
|
array->count = safeArray->rgsabound[0].cElements;
|
||||||
|
array->handle = safeArray;
|
||||||
|
|
||||||
|
return hrc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Release all items in the array and reset it.
|
||||||
|
*
|
||||||
|
* SafeArrayDestroy is aware of the item's type and calls release or free
|
||||||
|
* for each item according to its type. Therefore, vboxArrayUnalloc and
|
||||||
|
* vboxArrayRelease are the same for MSCOM.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
vboxArrayRelease(vboxArray *array)
|
||||||
|
{
|
||||||
|
if (array->handle == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SafeArrayUnaccessData(array->handle);
|
||||||
|
SafeArrayDestroy(array->handle);
|
||||||
|
|
||||||
|
array->items = NULL;
|
||||||
|
array->count = 0;
|
||||||
|
array->handle = NULL;
|
||||||
|
}
|
||||||
|
@ -30,4 +30,19 @@ extern PFNVBOXGETXPCOMCFUNCTIONS g_pfnGetFunctions;
|
|||||||
int VBoxCGlueInit(unsigned int *version);
|
int VBoxCGlueInit(unsigned int *version);
|
||||||
void VBoxCGlueTerm(void);
|
void VBoxCGlueTerm(void);
|
||||||
|
|
||||||
|
typedef struct _vboxArray vboxArray;
|
||||||
|
|
||||||
|
struct _vboxArray {
|
||||||
|
void **items;
|
||||||
|
size_t count;
|
||||||
|
void *handle;
|
||||||
|
};
|
||||||
|
|
||||||
|
# define VBOX_ARRAY_INITIALIZER { NULL, 0, NULL }
|
||||||
|
|
||||||
|
nsresult vboxArrayGet(vboxArray *array, void *self, void *getter);
|
||||||
|
nsresult vboxArrayGetWithArg(vboxArray *array, void *self, void *getter, void *arg);
|
||||||
|
void vboxArrayRelease(vboxArray *array);
|
||||||
|
# define vboxArrayUnalloc vboxArrayRelease
|
||||||
|
|
||||||
#endif /* __VBOX_MSCOMGLUE_H__ */
|
#endif /* __VBOX_MSCOMGLUE_H__ */
|
||||||
|
@ -253,3 +253,118 @@ VBoxCGlueTerm(void)
|
|||||||
pVBoxFuncs_v2_2 = NULL;
|
pVBoxFuncs_v2_2 = NULL;
|
||||||
g_pfnGetFunctions = NULL;
|
g_pfnGetFunctions = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* In XPCOM an array is represented by 1) a pointer to an array of pointers
|
||||||
|
* that point to the items and 2) an unsigned int representing the number of
|
||||||
|
* items in the array. When the items aren't needed anymore they are released
|
||||||
|
* or freed according to their type.
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef nsresult (*ArrayGetter)(void *self, PRUint32 *count, void ***items);
|
||||||
|
typedef nsresult (*ArrayGetterWithArg)(void *self, void *arg, PRUint32 *count, void ***items);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Call the getter with self as first argument and fill the array with the
|
||||||
|
* returned items.
|
||||||
|
*/
|
||||||
|
nsresult
|
||||||
|
vboxArrayGet(vboxArray *array, void *self, void *getter)
|
||||||
|
{
|
||||||
|
nsresult nsrc;
|
||||||
|
void **items = NULL;
|
||||||
|
PRUint32 count = 0;
|
||||||
|
|
||||||
|
array->items = NULL;
|
||||||
|
array->count = 0;
|
||||||
|
|
||||||
|
nsrc = ((ArrayGetter)getter)(self, &count, &items);
|
||||||
|
|
||||||
|
if (NS_FAILED(nsrc)) {
|
||||||
|
return nsrc;
|
||||||
|
}
|
||||||
|
|
||||||
|
array->items = items;
|
||||||
|
array->count = count;
|
||||||
|
|
||||||
|
return nsrc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Call the getter with self as first argument and arg as second argument
|
||||||
|
* and fill the array with the returned items.
|
||||||
|
*/
|
||||||
|
nsresult
|
||||||
|
vboxArrayGetWithArg(vboxArray *array, void *self, void *getter, void *arg)
|
||||||
|
{
|
||||||
|
nsresult nsrc;
|
||||||
|
void **items = NULL;
|
||||||
|
PRUint32 count = 0;
|
||||||
|
|
||||||
|
array->items = NULL;
|
||||||
|
array->count = 0;
|
||||||
|
|
||||||
|
nsrc = ((ArrayGetterWithArg)getter)(self, arg, &count, &items);
|
||||||
|
|
||||||
|
if (NS_FAILED(nsrc)) {
|
||||||
|
return nsrc;
|
||||||
|
}
|
||||||
|
|
||||||
|
array->items = items;
|
||||||
|
array->count = count;
|
||||||
|
|
||||||
|
return nsrc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Release all items in the array and reset it.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
vboxArrayRelease(vboxArray *array)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
nsISupports *supports;
|
||||||
|
|
||||||
|
if (array->items == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < array->count; ++i) {
|
||||||
|
supports = array->items[i];
|
||||||
|
|
||||||
|
if (supports != NULL) {
|
||||||
|
supports->vtbl->Release(supports);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
array->items = NULL;
|
||||||
|
array->count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Unalloc all items in the array and reset it.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
vboxArrayUnalloc(vboxArray *array)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
void *item;
|
||||||
|
|
||||||
|
if (array->items == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < array->count; ++i) {
|
||||||
|
item = array->items[i];
|
||||||
|
|
||||||
|
if (item != NULL) {
|
||||||
|
pVBoxFuncs_v2_2->pfnComUnallocMem(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
array->items = NULL;
|
||||||
|
array->count = 0;
|
||||||
|
}
|
||||||
|
@ -38,4 +38,18 @@ extern PFNVBOXGETXPCOMCFUNCTIONS g_pfnGetFunctions;
|
|||||||
int VBoxCGlueInit(unsigned int *version);
|
int VBoxCGlueInit(unsigned int *version);
|
||||||
void VBoxCGlueTerm(void);
|
void VBoxCGlueTerm(void);
|
||||||
|
|
||||||
|
typedef struct _vboxArray vboxArray;
|
||||||
|
|
||||||
|
struct _vboxArray {
|
||||||
|
void **items;
|
||||||
|
size_t count;
|
||||||
|
};
|
||||||
|
|
||||||
|
# define VBOX_ARRAY_INITIALIZER { NULL, 0 }
|
||||||
|
|
||||||
|
nsresult vboxArrayGet(vboxArray *array, void *self, void *getter);
|
||||||
|
nsresult vboxArrayGetWithArg(vboxArray *array, void *self, void *getter, void *arg);
|
||||||
|
void vboxArrayRelease(vboxArray *array);
|
||||||
|
void vboxArrayUnalloc(vboxArray *array);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user