VirtualBox

Changeset 49539 in vbox


Ignore:
Timestamp:
Nov 18, 2013 4:52:10 PM (11 years ago)
Author:
vboxsync
Message:

Main/cbinding: lots of love and care for this long forgotten part of the code, make it easier to use and more functional (error handling, initialization), and clean up and extend the sample code. It now includes the event sample, no need to keep so much redundant code.

Location:
trunk/src/VBox/Main/cbinding
Files:
1 deleted
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/cbinding/Makefile.kmk

    r48225 r49539  
    3030XpComCSamples_SOURCES = \
    3131        tstXPCOMCGlue.c \
    32         tstXPCOMCEvent.c \
    3332        makefile.tstXPCOMCGlue=>Makefile
    3433
     
    119118  tstXPCOMCGlue_LIBS = \
    120119        $(VBoxXPCOMCGlue_1_TARGET)
    121 
    122   #
    123   # The event listener testcase.
    124   #
    125   PROGRAMS += tstXPCOMCEvent
    126   tstXPCOMCEvent_TEMPLATE = VBOXR3TSTEXE
    127   tstXPCOMCEvent_INCS = \
    128         $(VBOX_PATH_SDK)/bindings/xpcom/include \
    129         $(VBOX_PATH_SDK)/bindings/xpcom/cbinding
    130   tstXPCOMCEvent_INTERMEDIATES = \
    131         $(VBOX_PATH_SDK)/bindings/xpcom/cbinding/VBoxXPCOMCGlue.h \
    132         $(VBOX_PATH_SDK)/bindings/xpcom/include/VBoxCAPI_v$(VBOX_API_VERSION).h
    133   tstXPCOMCEvent_SOURCES = \
    134         tstXPCOMCEvent.c
    135   tstXPCOMCEvent_LIBS = \
    136         $(VBoxXPCOMCGlue_1_TARGET)
    137120 endif
    138121
  • trunk/src/VBox/Main/cbinding/VBoxXPCOMC.cpp

    r44529 r49539  
    55
    66/*
    7  * Copyright (C) 2009-2012 Oracle Corporation
     7 * Copyright (C) 2009-2013 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    2020#include <nsIServiceManager.h>
    2121#include <nsEventQueueUtils.h>
     22#include <nsIExceptionService.h>
    2223
    2324#include <iprt/string.h>
     
    3132using namespace std;
    3233
    33 static ISession            *Session        = NULL;
    34 static IVirtualBox         *Ivirtualbox    = NULL;
    35 static nsIComponentManager *manager        = NULL;
    36 static nsIEventQueue       *eventQ         = NULL;
     34/* The following 3 object references should be eliminated once the legacy
     35 * way to initialize the XPCOM C bindings is removed. */
     36static ISession            *g_Session           = NULL;
     37static IVirtualBox         *g_VirtualBox        = NULL;
     38static nsIComponentManager *g_Manager           = NULL;
     39
     40static nsIEventQueue       *g_EventQueue        = NULL;
    3741
    3842static void VBoxComUninitialize(void);
     43static void VBoxClientUninitialize(void);
    3944
    4045static int
     
    6671{
    6772    if (ptr)
    68     {
    6973        nsMemory::Free(ptr);
    70     }
    7174}
    7275
     
    9497    }
    9598
    96     rc = NS_GetComponentManager (&manager);
     99    rc = NS_GetComponentManager(&g_Manager);
    97100    if (NS_FAILED(rc))
    98101    {
     
    102105    }
    103106
    104     rc = NS_GetMainEventQ (&eventQ);
     107    rc = NS_GetMainEventQ(&g_EventQueue);
    105108    if (NS_FAILED(rc))
    106109    {
     
    110113    }
    111114
    112     rc = manager->CreateInstanceByContractID(NS_VIRTUALBOX_CONTRACTID,
    113                                              nsnull,
    114                                              virtualBoxIID,
    115                                              (void **)ppVirtualBox);
     115    rc = g_Manager->CreateInstanceByContractID(NS_VIRTUALBOX_CONTRACTID,
     116                                               nsnull,
     117                                               virtualBoxIID,
     118                                               (void **)&g_VirtualBox);
    116119    if (NS_FAILED(rc))
    117120    {
     
    123126    Log(("Cbinding: IVirtualBox object created.\n"));
    124127
    125     rc = manager->CreateInstanceByContractID (NS_SESSION_CONTRACTID,
    126                                               nsnull,
    127                                               sessionIID,
    128                                               (void **)ppSession);
     128    rc = g_Manager->CreateInstanceByContractID(NS_SESSION_CONTRACTID,
     129                                               nsnull,
     130                                               sessionIID,
     131                                               (void **)&g_Session);
    129132    if (NS_FAILED(rc))
    130133    {
     
    136139    Log(("Cbinding: ISession object created.\n"));
    137140
    138     /* Store ppSession & ppVirtualBox so that VBoxComUninitialize
    139      * can later take care of them while cleanup
    140      */
    141     Session     = *ppSession;
    142     Ivirtualbox = *ppVirtualBox;
    143 
     141    *ppSession = g_Session;
     142    *ppVirtualBox = g_VirtualBox;
    144143}
    145144
     
    147146VBoxComInitializeV1(IVirtualBox **ppVirtualBox, ISession **ppSession)
    148147{
    149     /* stub that always fails. */
    150     *ppVirtualBox = NULL;
    151     *ppSession = NULL;
     148    VBoxComInitialize(IVIRTUALBOX_IID_STR, ppVirtualBox,
     149                      ISESSION_IID_STR, ppSession);
    152150}
    153151
     
    155153VBoxComUninitialize(void)
    156154{
    157     if (Session)
    158         NS_RELEASE(Session);        // decrement refcount
    159     if (Ivirtualbox)
    160         NS_RELEASE(Ivirtualbox);    // decrement refcount
    161     if (eventQ)
    162         NS_RELEASE(eventQ);         // decrement refcount
    163     if (manager)
    164         NS_RELEASE(manager);        // decrement refcount
     155    if (g_Session)
     156    {
     157        NS_RELEASE(g_Session);
     158        g_Session = NULL;
     159    }
     160    if (g_VirtualBox)
     161    {
     162        NS_RELEASE(g_VirtualBox);
     163        g_VirtualBox = NULL;
     164    }
     165    if (g_EventQueue)
     166    {
     167        NS_RELEASE(g_EventQueue);
     168        g_EventQueue = NULL;
     169    }
     170    if (g_Manager)
     171    {
     172        NS_RELEASE(g_Manager);
     173        g_Manager = NULL;
     174    }
    165175    com::Shutdown();
    166     Log(("Cbinding: Cleaned up the created IVirtualBox and ISession Objects.\n"));
    167 }
    168 
    169 static void
    170 VBoxGetEventQueue(nsIEventQueue **eventQueue)
    171 {
    172     *eventQueue = eventQ;
    173 }
    174 
    175 static uint32_t
     176    Log(("Cbinding: Cleaned up the created objects.\n"));
     177}
     178
     179static void
     180VBoxGetEventQueue(nsIEventQueue **ppEventQueue)
     181{
     182    *ppEventQueue = g_EventQueue;
     183}
     184
     185static nsresult
     186VBoxGetException(nsIException **ppException)
     187{
     188    nsresult rc;
     189
     190    *ppException = NULL;
     191    nsIServiceManager *mgr = NULL;
     192    rc = NS_GetServiceManager(&mgr);
     193    if (NS_FAILED(rc) || !mgr)
     194        return rc;
     195
     196    nsIID esid = NS_IEXCEPTIONSERVICE_IID;
     197    nsIExceptionService *es = NULL;
     198    rc = mgr->GetServiceByContractID(NS_EXCEPTIONSERVICE_CONTRACTID, esid, (void **)&es);
     199    if (NS_FAILED(rc) || !es)
     200    {
     201        NS_RELEASE(mgr);
     202        return rc;
     203    }
     204
     205    nsIExceptionManager *em;
     206    rc = es->GetCurrentExceptionManager(&em);
     207    if (NS_FAILED(rc) || !em)
     208    {
     209        NS_RELEASE(es);
     210        NS_RELEASE(mgr);
     211        return rc;
     212    }
     213
     214    nsIException *ex;
     215    rc = em->GetCurrentException(&ex);
     216    if (NS_FAILED(rc))
     217    {
     218        NS_RELEASE(em);
     219        NS_RELEASE(es);
     220        NS_RELEASE(mgr);
     221        return rc;
     222    }
     223
     224    *ppException = ex;
     225    NS_RELEASE(em);
     226    NS_RELEASE(es);
     227    NS_RELEASE(mgr);
     228    return rc;
     229}
     230
     231static nsresult
     232VBoxClearException(void)
     233{
     234    nsresult rc;
     235
     236    nsIServiceManager *mgr = NULL;
     237    rc = NS_GetServiceManager(&mgr);
     238    if (NS_FAILED(rc) || !mgr)
     239        return rc;
     240
     241    nsIID esid = NS_IEXCEPTIONSERVICE_IID;
     242    nsIExceptionService *es = NULL;
     243    rc = mgr->GetServiceByContractID(NS_EXCEPTIONSERVICE_CONTRACTID, esid, (void **)&es);
     244    if (NS_FAILED(rc) || !es)
     245    {
     246        NS_RELEASE(mgr);
     247        return rc;
     248    }
     249
     250    nsIExceptionManager *em;
     251    rc = es->GetCurrentExceptionManager(&em);
     252    if (NS_FAILED(rc) || !em)
     253    {
     254        NS_RELEASE(es);
     255        NS_RELEASE(mgr);
     256        return rc;
     257    }
     258
     259    rc = em->SetCurrentException(NULL);
     260    NS_RELEASE(em);
     261    NS_RELEASE(es);
     262    NS_RELEASE(mgr);
     263    return rc;
     264}
     265
     266static nsresult
     267VBoxClientInitialize(const char *pszVirtualBoxClientIID, IVirtualBoxClient **ppVirtualBoxClient)
     268{
     269    nsresult rc;
     270    nsID virtualBoxClientIID;
     271    nsID sessionIID;
     272
     273    *ppVirtualBoxClient = NULL;
     274
     275    /* convert the string representation of UUID to nsIID type */
     276    if (!virtualBoxClientIID.Parse(pszVirtualBoxClientIID))
     277        return NS_ERROR_INVALID_ARG;
     278
     279    rc = com::Initialize();
     280    if (NS_FAILED(rc))
     281    {
     282        Log(("Cbinding: XPCOM could not be initialized! rc=%Rhrc\n", rc));
     283        VBoxClientUninitialize();
     284        return rc;
     285    }
     286
     287    nsIComponentManager *pManager;
     288    rc = NS_GetComponentManager(&pManager);
     289    if (NS_FAILED(rc))
     290    {
     291        Log(("Cbinding: Could not get component manager! rc=%Rhrc\n", rc));
     292        VBoxClientUninitialize();
     293        return rc;
     294    }
     295
     296    rc = NS_GetMainEventQ(&g_EventQueue);
     297    if (NS_FAILED(rc))
     298    {
     299        Log(("Cbinding: Could not get xpcom event queue! rc=%Rhrc\n", rc));
     300        VBoxClientUninitialize();
     301        return rc;
     302    }
     303
     304    rc = pManager->CreateInstanceByContractID(NS_VIRTUALBOXCLIENT_CONTRACTID,
     305                                              nsnull,
     306                                              virtualBoxClientIID,
     307                                              (void **)ppVirtualBoxClient);
     308    if (NS_FAILED(rc))
     309    {
     310        Log(("Cbinding: Could not instantiate VirtualBoxClient object! rc=%Rhrc\n",rc));
     311        VBoxClientUninitialize();
     312        return rc;
     313    }
     314
     315    NS_RELEASE(pManager);
     316    pManager = NULL;
     317
     318    Log(("Cbinding: IVirtualBoxClient object created.\n"));
     319
     320    return NS_OK;
     321}
     322
     323static void
     324VBoxClientUninitialize(void)
     325{
     326    if (g_EventQueue)
     327    {
     328        NS_RELEASE(g_EventQueue);
     329        g_EventQueue = NULL;
     330    }
     331    com::Shutdown();
     332    Log(("Cbinding: Cleaned up the created objects.\n"));
     333}
     334
     335static unsigned int
    176336VBoxVersion(void)
    177337{
    178     uint32_t version = 0;
    179 
    180     version = (VBOX_VERSION_MAJOR * 1000 * 1000) + (VBOX_VERSION_MINOR * 1000) + (VBOX_VERSION_BUILD);
    181 
    182     return version;
     338    return VBOX_VERSION_MAJOR * 1000 * 1000 + VBOX_VERSION_MINOR * 1000 + VBOX_VERSION_BUILD;
     339}
     340
     341static unsigned int
     342VBoxAPIVersion(void)
     343{
     344    return VBOX_VERSION_MAJOR * 1000 + VBOX_VERSION_MINOR + (VBOX_VERSION_BUILD > 50 ? 1 : 0);
    183345}
    184346
     
    195357
    196358        VBoxVersion,
     359        VBoxAPIVersion,
     360
     361        VBoxClientInitialize,
     362        VBoxClientUninitialize,
     363
     364        VBoxComInitialize,
     365        VBoxComUninitialize,
     366
     367        VBoxComUnallocMem,
     368
     369        VBoxUtf16ToUtf8,
     370        VBoxUtf8ToUtf16,
     371        VBoxUtf8Free,
     372        VBoxUtf16Free,
     373
     374        VBoxGetEventQueue,
     375        VBoxGetException,
     376        VBoxClearException,
     377
     378        VBOX_XPCOMC_VERSION
     379    };
     380
     381    if ((uVersion & 0xffff0000U) == (VBOX_XPCOMC_VERSION & 0xffff0000U))
     382        return &s_Functions;
     383
     384    /*
     385     * Legacy interface version 2.0.
     386     */
     387    static const struct VBOXXPCOMCV2
     388    {
     389        /** The size of the structure. */
     390        unsigned cb;
     391        /** The structure version. */
     392        unsigned uVersion;
     393
     394        unsigned int (*pfnGetVersion)(void);
     395
     396        void  (*pfnComInitialize)(const char *pszVirtualBoxIID,
     397                                  IVirtualBox **ppVirtualBox,
     398                                  const char *pszSessionIID,
     399                                  ISession **ppSession);
     400
     401        void  (*pfnComUninitialize)(void);
     402
     403        void  (*pfnComUnallocMem)(void *pv);
     404        void  (*pfnUtf16Free)(PRUnichar *pwszString);
     405        void  (*pfnUtf8Free)(char *pszString);
     406
     407        int   (*pfnUtf16ToUtf8)(const PRUnichar *pwszString, char **ppszString);
     408        int   (*pfnUtf8ToUtf16)(const char *pszString, PRUnichar **ppwszString);
     409
     410        void  (*pfnGetEventQueue)(nsIEventQueue **ppEventQueue);
     411
     412        /** Tail version, same as uVersion. */
     413        unsigned uEndVersion;
     414    } s_Functions_v2_0 =
     415    {
     416        sizeof(s_Functions_v2_0),
     417        0x00020000U,
     418
     419        VBoxVersion,
    197420
    198421        VBoxComInitialize,
     
    208431        VBoxGetEventQueue,
    209432
    210         VBOX_XPCOMC_VERSION
     433        0x00020000U
    211434    };
    212435
    213     if ((uVersion & 0xffff0000U) == (VBOX_XPCOMC_VERSION & 0xffff0000U))
    214         return &s_Functions;
     436    if ((uVersion & 0xffff0000U) == 0x00020000U)
     437        return (PCVBOXXPCOM)&s_Functions_v2_0;
    215438
    216439    /*
  • trunk/src/VBox/Main/cbinding/VBoxXPCOMCGlue.c

    r33396 r49539  
    55
    66/*
    7  * Copyright (C) 2008-2010 Oracle Corporation
     7 * Copyright (C) 2008-2013 Oracle Corporation
    88 *
    99 * Permission is hereby granted, free of charge, to any person
     
    3838#include <stdint.h>
    3939#include <dlfcn.h>
     40#include <pthread.h>
    4041
    4142#include "VBoxXPCOMCGlue.h"
     
    6869PFNVBOXGETXPCOMCFUNCTIONS g_pfnGetFunctions = NULL;
    6970
     71typedef void FNDUMMY(void);
     72typedef FNDUMMY *PFNDUMMY;
     73/** Just a dummy global structure containing a bunch of
     74 * function pointers to code which is wanted in the link.
     75 * In this case this is for helping gdb as it gets hideously
     76 * confused if the application doesn't drag in pthreads.
     77 */
     78PFNDUMMY g_apfnVBoxXPCOMCGlue[] =
     79{
     80    (PFNDUMMY)pthread_create
     81};
     82
    7083
    7184/**
  • trunk/src/VBox/Main/cbinding/makefile.tstXPCOMCGlue

    r48225 r49539  
    11# $Revision$
    2 ## @file makefile.tstLinuxC
     2## @file makefile.tstXPCOMCGlue
    33# Makefile for sample program illustrating use of C binding for XPCOM.
    44#
     
    2424
    2525.PHONY: all
    26 all: tstXPCOMCGlue tstXPCOMCEvent
     26all: tstXPCOMCGlue
    2727
    2828.PHONY: clean
    2929clean:
    30         rm -f tstXPCOMCGlue.o tstXPCOMCGlue VBoxXPCOMCGlue.o tstXPCOMCEvent.o tstXPCOMCEvent
     30        rm -f tstXPCOMCGlue.o tstXPCOMCGlue VBoxXPCOMCGlue.o
    3131
    3232tstXPCOMCGlue: tstXPCOMCGlue.o VBoxXPCOMCGlue.o
    33         $(CC) -o $@ $^ -ldl
     33        $(CC) -o $@ $^ -ldl -lpthread
    3434
    3535tstXPCOMCGlue.o: tstXPCOMCGlue.c
    3636        $(CC) $(CFLAGS) $(INCS_XPCOM) $(GLUE_INC) -o $@ -c $<
    3737
    38 tstXPCOMCEvent: tstXPCOMCEvent.o VBoxXPCOMCGlue.o
    39         $(CC) -o $@ $^ -ldl -lpthread
    40 
    41 tstXPCOMCEvent.o: tstXPCOMCEvent.c
    42         $(CC) $(CFLAGS) $(INCS_XPCOM) $(GLUE_INC) -o $@ -c $<
    43 
    4438VBoxXPCOMCGlue.o: $(GLUE_DIR)/VBoxXPCOMCGlue.c
    4539        $(CC) $(CFLAGS) $(INCS_XPCOM) $(GLUE_INC) -o $@ -c $<
  • trunk/src/VBox/Main/cbinding/tstXPCOMCGlue.c

    r48225 r49539  
    11/* $Revision$ */
    22/** @file tstXPCOMCGlue.c
    3  * Demonstrator program to illustrate use of C bindings of Main API.
     3 * Demonstrator program to illustrate use of C bindings of Main API, including
     4 * how to retrieve all available error information.
     5 *
     6 * This includes code which shows how to handle active event listeners
     7 * (event delivery through callbacks), which is not so frequently seen in
     8 * other samples which mostly use passive event listeners.
    49 *
    510 * Linux only at the moment due to shared library magic in the Makefile.
     
    2530#include <string.h>
    2631#include <stdlib.h>
     32#include <unistd.h>
     33#include <signal.h>
     34#include <sys/poll.h>
     35
     36/*******************************************************************************
     37*   Global Variables                                                           *
     38*******************************************************************************/
     39/** Set by signal handler. */
     40static volatile int g_fStop = 0;
     41
     42static const char *GetStateName(PRUint32 machineState)
     43{
     44    switch (machineState)
     45    {
     46        case MachineState_Null:                return "<null>";
     47        case MachineState_PoweredOff:          return "PoweredOff";
     48        case MachineState_Saved:               return "Saved";
     49        case MachineState_Teleported:          return "Teleported";
     50        case MachineState_Aborted:             return "Aborted";
     51        case MachineState_Running:             return "Running";
     52        case MachineState_Paused:              return "Paused";
     53        case MachineState_Stuck:               return "Stuck";
     54        case MachineState_Teleporting:         return "Teleporting";
     55        case MachineState_LiveSnapshotting:    return "LiveSnapshotting";
     56        case MachineState_Starting:            return "Starting";
     57        case MachineState_Stopping:            return "Stopping";
     58        case MachineState_Saving:              return "Saving";
     59        case MachineState_Restoring:           return "Restoring";
     60        case MachineState_TeleportingPausedVM: return "TeleportingPausedVM";
     61        case MachineState_TeleportingIn:       return "TeleportingIn";
     62        case MachineState_FaultTolerantSyncing: return "FaultTolerantSyncing";
     63        case MachineState_DeletingSnapshotOnline: return "DeletingSnapshotOnline";
     64        case MachineState_DeletingSnapshotPaused: return "DeletingSnapshotPaused";
     65        case MachineState_RestoringSnapshot:   return "RestoringSnapshot";
     66        case MachineState_DeletingSnapshot:    return "DeletingSnapshot";
     67        case MachineState_SettingUp:           return "SettingUp";
     68        default:                               return "no idea";
     69    }
     70}
     71
     72struct IEventListenerDemo_vtbl
     73{
     74    struct IEventListener_vtbl ieventlistener;
     75};
     76
     77typedef struct IEventListenerDemo
     78{
     79    struct IEventListenerDemo_vtbl *vtbl;
     80
     81    int refcount;
     82} IEventListenerDemo;
    2783
    2884/**
    29  * Start a VM.
     85 * Event handler function
     86 */
     87static nsresult IEventListenerDemo_HandleEvent(IEventListener *pThis, IEvent *event)
     88{
     89    enum VBoxEventType evType;
     90    nsresult rc;
     91
     92    if (!event)
     93    {
     94        printf("event null\n");
     95        return NS_OK;
     96    }
     97
     98    evType = VBoxEventType_Invalid;
     99    rc = event->vtbl->GetType(event, &evType);
     100    if (NS_FAILED(rc))
     101    {
     102        printf("cannot get event type, rc=%#x\n", rc);
     103        return NS_OK;
     104    }
     105
     106    switch (evType)
     107    {
     108        case VBoxEventType_OnMousePointerShapeChanged:
     109            printf("OnMousePointerShapeChanged\n");
     110            break;
     111
     112        case VBoxEventType_OnMouseCapabilityChanged:
     113            printf("OnMouseCapabilityChanged\n");
     114            break;
     115
     116        case VBoxEventType_OnKeyboardLedsChanged:
     117            printf("OnMouseCapabilityChanged\n");
     118            break;
     119
     120        case VBoxEventType_OnStateChanged:
     121        {
     122            static const nsID istateChangedEventUUID = ISTATECHANGEDEVENT_IID;
     123            IStateChangedEvent *ev = NULL;
     124            enum MachineState state;
     125            rc = event->vtbl->nsisupports.QueryInterface((nsISupports *)event, &istateChangedEventUUID, (void **)&ev);
     126            if (NS_FAILED(rc))
     127            {
     128                printf("cannot get StateChangedEvent interface, rc=%#x\n", rc);
     129                return NS_OK;
     130            }
     131            if (!ev)
     132            {
     133                printf("StateChangedEvent reference null\n");
     134                return NS_OK;
     135            }
     136            rc = ev->vtbl->GetState(ev, &state);
     137            if (NS_FAILED(rc))
     138                printf("warning: cannot get state, rc=%#x\n", rc);
     139            ev->vtbl->ievent.nsisupports.Release((nsISupports *)ev);
     140            printf("OnStateChanged: %s\n", GetStateName(state));
     141
     142            fflush(stdout);
     143            if (   state == MachineState_PoweredOff
     144                || state == MachineState_Saved
     145                || state == MachineState_Teleported
     146                || state == MachineState_Aborted
     147               )
     148                g_fStop = 1;
     149            break;
     150        }
     151
     152        case VBoxEventType_OnAdditionsStateChanged:
     153            printf("OnAdditionsStateChanged\n");
     154            break;
     155
     156        case VBoxEventType_OnNetworkAdapterChanged:
     157            printf("OnNetworkAdapterChanged\n");
     158            break;
     159
     160        case VBoxEventType_OnSerialPortChanged:
     161            printf("OnSerialPortChanged\n");
     162            break;
     163
     164        case VBoxEventType_OnParallelPortChanged:
     165            printf("OnParallelPortChanged\n");
     166            break;
     167
     168        case VBoxEventType_OnStorageControllerChanged:
     169            printf("OnStorageControllerChanged\n");
     170            break;
     171
     172        case VBoxEventType_OnMediumChanged:
     173            printf("OnMediumChanged\n");
     174            break;
     175
     176        case VBoxEventType_OnVRDEServerChanged:
     177            printf("OnVRDEServerChanged\n");
     178            break;
     179
     180        case VBoxEventType_OnUSBControllerChanged:
     181            printf("OnUSBControllerChanged\n");
     182            break;
     183
     184        case VBoxEventType_OnUSBDeviceStateChanged:
     185            printf("OnUSBDeviceStateChanged\n");
     186            break;
     187
     188        case VBoxEventType_OnSharedFolderChanged:
     189            printf("OnSharedFolderChanged\n");
     190            break;
     191
     192        case VBoxEventType_OnRuntimeError:
     193            printf("OnRuntimeError\n");
     194            break;
     195
     196        case VBoxEventType_OnCanShowWindow:
     197            printf("OnCanShowWindow\n");
     198            break;
     199        case VBoxEventType_OnShowWindow:
     200            printf("OnShowWindow\n");
     201            break;
     202
     203        default:
     204            printf("unknown event: %d\n", evType);
     205    }
     206
     207    return NS_OK;
     208}
     209
     210static nsresult IEventListenerDemo_QueryInterface(nsISupports *pThis, const nsID *iid, void **resultp)
     211{
     212    static const nsID ieventListenerUUID = IEVENTLISTENER_IID;
     213    static const nsID isupportIID = NS_ISUPPORTS_IID;
     214
     215    /* match iid */
     216    if (    memcmp(iid, &ieventListenerUUID, sizeof(nsID)) == 0
     217        ||  memcmp(iid, &isupportIID, sizeof(nsID)) == 0)
     218    {
     219        pThis->vtbl->AddRef(pThis);
     220        *resultp = pThis;
     221        return NS_OK;
     222    }
     223
     224    return NS_NOINTERFACE;
     225}
     226
     227static nsresult IEventListenerDemo_AddRef(nsISupports *pThis)
     228{
     229    return ++(((IEventListenerDemo *)pThis)->refcount);
     230}
     231
     232static nsresult IEventListenerDemo_Release(nsISupports *pThis)
     233{
     234    nsresult c;
     235
     236    c = --(((IEventListenerDemo *)pThis)->refcount);
     237    if (c == 0)
     238        free(pThis);
     239    return c;
     240}
     241
     242struct IEventListenerDemo_vtbl_int_gcc
     243{
     244    ptrdiff_t offset_to_top;
     245    void *typeinfo;
     246    struct IEventListenerDemo_vtbl vtbl;
     247};
     248
     249static struct IEventListenerDemo_vtbl_int_gcc g_IEventListenerDemo_vtbl_int_gcc =
     250{
     251    0,      /* offset_to_top */
     252    NULL,   /* typeinfo, not vital */
     253    {
     254        {
     255            {
     256                IEventListenerDemo_QueryInterface,
     257                IEventListenerDemo_AddRef,
     258                IEventListenerDemo_Release
     259            },
     260            IEventListenerDemo_HandleEvent
     261        }
     262    }
     263};
     264
     265/**
     266 * Signal handler, terminate event listener.
     267 *
     268 * @param  iSig     The signal number (ignored).
     269 */
     270static void sigIntHandler(int iSig)
     271{
     272    (void)iSig;
     273    g_fStop = 1;
     274}
     275
     276/**
     277 * Register event listener for the selected VM.
    30278 *
    31279 * @param   virtualBox ptr to IVirtualBox object
    32280 * @param   session    ptr to ISession object
    33281 * @param   id         identifies the machine to start
     282 * @param   queue      handle to the event queue
    34283 */
    35 static void startVM(IVirtualBox *virtualBox, ISession *session, PRUnichar *id)
     284static void registerEventListener(IVirtualBox *virtualBox, ISession *session, PRUnichar *machineId, nsIEventQueue *queue)
     285{
     286    IConsole *console = NULL;
     287    nsresult rc;
     288
     289    rc = session->vtbl->GetConsole(session, &console);
     290    if ((NS_SUCCEEDED(rc)) && console)
     291    {
     292        IEventSource *es = NULL;
     293        rc = console->vtbl->GetEventSource(console, &es);
     294        if (NS_SUCCEEDED(rc) && es)
     295        {
     296            PRUint32 interestingEvents[] =
     297                {
     298                    VBoxEventType_OnMousePointerShapeChanged,
     299                    VBoxEventType_OnMouseCapabilityChanged,
     300                    VBoxEventType_OnKeyboardLedsChanged,
     301                    VBoxEventType_OnStateChanged,
     302                    VBoxEventType_OnAdditionsStateChanged,
     303                    VBoxEventType_OnNetworkAdapterChanged,
     304                    VBoxEventType_OnSerialPortChanged,
     305                    VBoxEventType_OnParallelPortChanged,
     306                    VBoxEventType_OnStorageControllerChanged,
     307                    VBoxEventType_OnMediumChanged,
     308                    VBoxEventType_OnVRDEServerChanged,
     309                    VBoxEventType_OnUSBControllerChanged,
     310                    VBoxEventType_OnUSBDeviceStateChanged,
     311                    VBoxEventType_OnSharedFolderChanged,
     312                    VBoxEventType_OnRuntimeError,
     313                    VBoxEventType_OnCanShowWindow,
     314                    VBoxEventType_OnShowWindow
     315                };
     316            IEventListenerDemo *consoleListener = NULL;
     317            consoleListener = calloc(1, sizeof(IEventListenerDemo));
     318            if (consoleListener)
     319            {
     320                consoleListener->vtbl = &(g_IEventListenerDemo_vtbl_int_gcc.vtbl);
     321                consoleListener->vtbl->ieventlistener.nsisupports.AddRef((nsISupports *)consoleListener);
     322
     323                rc = es->vtbl->RegisterListener(es, (IEventListener *)consoleListener,
     324                                                sizeof(interestingEvents) / sizeof(interestingEvents[0]),
     325                                                interestingEvents, 1 /* active */);
     326                if (NS_SUCCEEDED(rc))
     327                {
     328                    /* Just wait here for events, no easy way to do this better
     329                     * as there's not much to do after this completes. */
     330                    PRInt32 fd;
     331                    int ret;
     332                    printf("Entering event loop, PowerOff the machine to exit or press Ctrl-C to terminate\n");
     333                    fflush(stdout);
     334                    signal(SIGINT, sigIntHandler);
     335
     336                    fd = queue->vtbl->GetEventQueueSelectFD(queue);
     337                    if (fd >= 0)
     338                    {
     339                        while (!g_fStop)
     340                        {
     341                            struct pollfd pfd;
     342
     343                            pfd.fd = fd;
     344                            pfd.events = POLLIN | POLLERR | POLLHUP;
     345                            pfd.revents = 0;
     346
     347                            ret = poll(&pfd, 1, 250);
     348
     349                            if (ret <= 0)
     350                                continue;
     351
     352                            if (pfd.revents & POLLHUP)
     353                                g_fStop = 1;
     354
     355                            queue->vtbl->ProcessPendingEvents(queue);
     356                        }
     357                    }
     358                    else
     359                    {
     360                        while (!g_fStop)
     361                        {
     362                            PLEvent *pEvent = NULL;
     363                            rc = queue->vtbl->WaitForEvent(queue, &pEvent);
     364                            if (NS_SUCCEEDED(rc))
     365                                queue->vtbl->HandleEvent(queue, pEvent);
     366                        }
     367                    }
     368                    signal(SIGINT, SIG_DFL);
     369                }
     370                es->vtbl->UnregisterListener(es, (IEventListener *)consoleListener);
     371                consoleListener->vtbl->ieventlistener.nsisupports.Release((nsISupports *)consoleListener);
     372            }
     373            else
     374            {
     375                printf("Failed while allocating memory for console event listener.\n");
     376            }
     377            es->vtbl->nsisupports.Release((nsISupports *)es);
     378        }
     379        console->vtbl->nsisupports.Release((nsISupports *)console);
     380    }
     381}
     382
     383/**
     384 * Print detailed error information if available.
     385 * @param   pszExecutable   string with the executable name
     386 * @param   pszErrorMsg     string containing the code location specific error message
     387 * @param   rc              XPCOM result code
     388 */
     389static void PrintErrorInfo(const char *pszExecutable, const char *pszErrorMsg, nsresult rc)
     390{
     391    nsIException *ex;
     392    nsresult rc2 = NS_OK;
     393    fprintf(stderr, "%s: %s (rc=%#010x)\n", pszExecutable, pszErrorMsg, (unsigned)rc);
     394    rc2 = g_pVBoxFuncs->pfnGetException(&ex);
     395    if (NS_SUCCEEDED(rc2))
     396    {
     397        static const nsID vbei = IVIRTUALBOXERRORINFO_IID;
     398        IVirtualBoxErrorInfo *ei;
     399        rc2 = ex->vtbl->nsisupports.QueryInterface((nsISupports *)ex, &vbei, (void **)&ei);
     400        if (NS_FAILED(rc2))
     401            ei = NULL;
     402        if (ei)
     403        {
     404            /* got extended error info, maybe multiple infos */
     405            do
     406            {
     407                PRInt32 resultCode = NS_OK;
     408                PRUnichar *componentUtf16 = NULL;
     409                char *component = NULL;
     410                PRUnichar *textUtf16 = NULL;
     411                char *text = NULL;
     412                IVirtualBoxErrorInfo *ei_next = NULL;
     413                fprintf(stderr, "Extended error info (IVirtualBoxErrorInfo):\n");
     414
     415                ei->vtbl->GetResultCode(ei, &resultCode);
     416                fprintf(stderr, "  resultCode=%#010x\n", (unsigned)resultCode);
     417
     418                ei->vtbl->GetComponent(ei, &componentUtf16);
     419                g_pVBoxFuncs->pfnUtf16ToUtf8(componentUtf16, &component);
     420                g_pVBoxFuncs->pfnComUnallocMem(componentUtf16);
     421                fprintf(stderr, "  component=%s\n", component);
     422                g_pVBoxFuncs->pfnUtf8Free(component);
     423
     424                ei->vtbl->GetText(ei, &textUtf16);
     425                g_pVBoxFuncs->pfnUtf16ToUtf8(textUtf16, &text);
     426                g_pVBoxFuncs->pfnComUnallocMem(textUtf16);
     427                fprintf(stderr, "  text=%s\n", text);
     428                g_pVBoxFuncs->pfnUtf8Free(text);
     429
     430                rc2 = ei->vtbl->GetNext(ei, &ei_next);
     431                if (NS_FAILED(rc2))
     432                    ei_next = NULL;
     433                ei->vtbl->nsiexception.nsisupports.Release((nsISupports *)ei);
     434                ei = ei_next;
     435            }
     436            while (ei);
     437        }
     438        else
     439        {
     440            /* got basic error info */
     441            nsresult resultCode = NS_OK;
     442            PRUnichar *messageUtf16 = NULL;
     443            char *message = NULL;
     444            fprintf(stderr, "Basic error info (nsIException):\n");
     445
     446            ex->vtbl->GetResult(ex, &resultCode);
     447            fprintf(stderr, "  resultCode=%#010x\n", resultCode);
     448
     449            ex->vtbl->GetMessage(ex, &messageUtf16);
     450            g_pVBoxFuncs->pfnUtf16ToUtf8(messageUtf16, &message);
     451            g_pVBoxFuncs->pfnComUnallocMem(messageUtf16);
     452            fprintf(stderr, "  message=%s\n", message);
     453            g_pVBoxFuncs->pfnUtf8Free(message);
     454        }
     455
     456        ex->vtbl->nsisupports.Release((nsISupports *)ex);
     457        g_pVBoxFuncs->pfnClearException();
     458    }
     459}
     460
     461/**
     462 * Start a VM.
     463 *
     464 * @param   argv0       executable name
     465 * @param   virtualBox  ptr to IVirtualBox object
     466 * @param   session     ptr to ISession object
     467 * @param   id          identifies the machine to start
     468 * @param   queue       ptr to event queue
     469 */
     470static void startVM(const char *argv0, IVirtualBox *virtualBox, ISession *session, PRUnichar *id, nsIEventQueue *queue)
    36471{
    37472    nsresult rc;
     
    42477
    43478    rc = virtualBox->vtbl->FindMachine(virtualBox, id, &machine);
    44 
    45479    if (NS_FAILED(rc) || !machine)
    46480    {
    47         fprintf(stderr, "Error: Couldn't get the machine handle.\n");
     481        PrintErrorInfo(argv0, "Error: Couldn't get the Machine reference", rc);
    48482        return;
    49483    }
    50484
    51485    g_pVBoxFuncs->pfnUtf8ToUtf16("gui", &sessionType);
    52 
    53486    rc = machine->vtbl->LaunchVMProcess(machine,
    54487        session,
     
    57490        &progress
    58491    );
    59 
    60492    g_pVBoxFuncs->pfnUtf16Free(sessionType);
    61 
    62     if (NS_FAILED(rc))
    63     {
    64         fprintf(stderr, "Error: OpenRemoteSession failed.\n");
    65     }
    66     else
     493    if (NS_SUCCEEDED(rc))
    67494    {
    68495        PRBool completed;
     
    74501        rc = progress->vtbl->GetCompleted(progress, &completed);
    75502        if (NS_FAILED(rc))
    76         {
    77             fprintf (stderr, "Error: GetCompleted status failed.\n");
    78         }
     503            fprintf(stderr, "Error: GetCompleted status failed\n");
    79504
    80505        progress->vtbl->GetResultCode(progress, &resultCode);
     
    95520        else
    96521        {
    97             fprintf(stderr, "Remote session has been successfully opened.\n");
     522            fprintf(stderr, "VM process has been successfully started\n");
     523
     524            /* Kick off the event listener demo part, which is quite separate.
     525             * Ignore it if you need a more basic sample. */
     526            registerEventListener(virtualBox, session, id, queue);
    98527        }
    99528        progress->vtbl->nsisupports.Release((nsISupports *)progress);
    100529    }
     530    else
     531        PrintErrorInfo(argv0, "Error: LaunchVMProcess failed", rc);
    101532
    102533    /* It's important to always release resources. */
     
    107538 * List the registered VMs.
    108539 *
    109  * @param   virtualBox ptr to IVirtualBox object
    110  * @param   session    ptr to ISession object
     540 * @param   argv0       executable name
     541 * @param   virtualBox  ptr to IVirtualBox object
     542 * @param   session     ptr to ISession object
     543 * @param   queue       ptr to event queue
    111544 */
    112 static void listVMs(IVirtualBox *virtualBox, ISession *session)
     545static void listVMs(const char *argv0, IVirtualBox *virtualBox, ISession *session, nsIEventQueue *queue)
    113546{
    114547    nsresult rc;
     
    125558    if (NS_FAILED(rc))
    126559    {
    127         fprintf(stderr, "could not get list of machines, rc=%08x\n",
    128             (unsigned)rc);
     560        PrintErrorInfo(argv0, "could not get list of machines", rc);
    129561        return;
    130562    }
     
    164596            machine->vtbl->GetName(machine, &machineNameUtf16);
    165597            g_pVBoxFuncs->pfnUtf16ToUtf8(machineNameUtf16,&machineName);
     598            g_pVBoxFuncs->pfnComUnallocMem(machineNameUtf16);
    166599            printf("\tName:        %s\n", machineName);
    167 
    168600            g_pVBoxFuncs->pfnUtf8Free(machineName);
    169             g_pVBoxFuncs->pfnComUnallocMem(machineNameUtf16);
    170601        }
    171602        else
     
    175606
    176607        {
    177             PRUnichar *uuidUtf16 = NULL;
    178             char      *uuidUtf8  = NULL;
     608            PRUnichar *uuidUtf16;
     609            char      *uuidUtf8;
    179610
    180611            machine->vtbl->GetId(machine, &uuidUtf16);
    181612            g_pVBoxFuncs->pfnUtf16ToUtf8(uuidUtf16, &uuidUtf8);
     613            g_pVBoxFuncs->pfnComUnallocMem(uuidUtf16);
    182614            printf("\tUUID:        %s\n", uuidUtf8);
    183 
    184615            g_pVBoxFuncs->pfnUtf8Free(uuidUtf8);
    185             g_pVBoxFuncs->pfnUtf16Free(uuidUtf16);
    186616        }
    187617
     
    189619        {
    190620            {
    191                 PRUnichar *configFile;
    192                 char      *configFile1 = calloc((size_t)64, (size_t)1);
    193 
    194                 machine->vtbl->GetSettingsFilePath(machine, &configFile);
    195                 g_pVBoxFuncs->pfnUtf16ToUtf8(configFile, &configFile1);
    196                 printf("\tConfig file: %s\n", configFile1);
    197 
    198                 free(configFile1);
    199                 g_pVBoxFuncs->pfnComUnallocMem(configFile);
     621                PRUnichar *configFileUtf16;
     622                char      *configFileUtf8;
     623
     624                machine->vtbl->GetSettingsFilePath(machine, &configFileUtf16);
     625                g_pVBoxFuncs->pfnUtf16ToUtf8(configFileUtf16, &configFileUtf8);
     626                g_pVBoxFuncs->pfnComUnallocMem(configFileUtf16);
     627                printf("\tConfig file: %s\n", configFileUtf8);
     628                g_pVBoxFuncs->pfnUtf8Free(configFileUtf8);
    200629            }
    201630
     
    215644                machine->vtbl->GetOSTypeId(machine, &typeId);
    216645                virtualBox->vtbl->GetGuestOSType(virtualBox, typeId, &osType);
     646                g_pVBoxFuncs->pfnComUnallocMem(typeId);
    217647                osType->vtbl->GetDescription(osType, &osNameUtf16);
    218648                g_pVBoxFuncs->pfnUtf16ToUtf8(osNameUtf16,&osName);
     649                g_pVBoxFuncs->pfnComUnallocMem(osNameUtf16);
    219650                printf("\tGuest OS:    %s\n\n", osName);
     651                g_pVBoxFuncs->pfnUtf8Free(osName);
    220652
    221653                osType->vtbl->nsisupports.Release((nsISupports *)osType);
    222                 g_pVBoxFuncs->pfnUtf8Free(osName);
    223                 g_pVBoxFuncs->pfnComUnallocMem(osNameUtf16);
    224                 g_pVBoxFuncs->pfnComUnallocMem(typeId);
    225654            }
    226655        }
     
    244673
    245674            machine->vtbl->GetId(machine, &uuidUtf16);
    246             startVM(virtualBox, session, uuidUtf16);
    247 
    248             g_pVBoxFuncs->pfnUtf16Free(uuidUtf16);
     675            startVM(argv0, virtualBox, session, uuidUtf16, queue);
     676            g_pVBoxFuncs->pfnComUnallocMem(uuidUtf16);
    249677        }
    250678    }
     
    263691        }
    264692    }
     693    if (machines)
     694        g_pVBoxFuncs->pfnComUnallocMem(machines);
    265695}
    266696
     
    269699int main(int argc, char **argv)
    270700{
     701    IVirtualBoxClient *vboxclient = NULL;
    271702    IVirtualBox *vbox            = NULL;
    272703    ISession   *session          = NULL;
     704    nsIEventQueue *queue         = NULL;
    273705    PRUint32    revision         = 0;
    274706    PRUnichar  *versionUtf16     = NULL;
     
    276708    nsresult    rc;     /* Result code of various function (method) calls. */
    277709
    278     printf("Starting Main\n");
    279 
    280     /*
    281      * VBoxComInitialize does all the necessary startup action and
    282      * provides us with pointers to vbox and session handles.
    283      * It should be matched by a call to VBoxComUninitialize(vbox)
    284      * when done.
    285      */
     710    printf("Starting main()\n");
    286711
    287712    if (VBoxCGlueInit() != 0)
     
    292717    }
    293718
    294     g_pVBoxFuncs->pfnComInitialize(IVIRTUALBOX_IID_STR, &vbox,
    295                                    ISESSION_IID_STR, &session);
    296     if (vbox == NULL)
    297     {
    298         fprintf(stderr, "%s: FATAL: could not get vbox handle\n", argv[0]);
     719    {
     720        unsigned ver = g_pVBoxFuncs->pfnGetVersion();
     721        printf("VirtualBox version: %u.%u.%u\n", ver / 1000000, ver / 1000 % 1000, ver % 1000);
     722        ver = g_pVBoxFuncs->pfnGetAPIVersion();
     723        printf("VirtualBox API version: %u.%u\n", ver / 1000, ver % 1000);
     724    }
     725
     726    g_pVBoxFuncs->pfnClientInitialize(IVIRTUALBOXCLIENT_IID_STR, &vboxclient);
     727    if (vboxclient == NULL)
     728    {
     729        fprintf(stderr, "%s: FATAL: could not get VirtualBoxClient reference\n", argv[0]);
    299730        return EXIT_FAILURE;
    300731    }
    301     if (session == NULL)
    302     {
    303         fprintf(stderr, "%s: FATAL: could not get session handle\n", argv[0]);
     732
     733    printf("----------------------------------------------------\n");
     734
     735    rc = vboxclient->vtbl->GetVirtualBox(vboxclient, &vbox);
     736    if (NS_FAILED(rc) || !vbox)
     737    {
     738        PrintErrorInfo(argv[0], "FATAL: could not get VirtualBox reference", rc);
    304739        return EXIT_FAILURE;
    305740    }
     741    rc = vboxclient->vtbl->GetSession(vboxclient, &session);
     742    if (NS_FAILED(rc) || !session)
     743    {
     744        PrintErrorInfo(argv[0], "FATAL: could not get Session reference", rc);
     745        return EXIT_FAILURE;
     746    }
     747
     748    g_pVBoxFuncs->pfnGetEventQueue(&queue);
    306749
    307750    /*
     
    311754     */
    312755
    313     printf("----------------------------------------------------\n");
    314 
    315756    /* 1. Revision */
    316757
    317758    rc = vbox->vtbl->GetRevision(vbox, &revision);
    318759    if (NS_SUCCEEDED(rc))
    319     {
    320760        printf("\tRevision: %u\n", revision);
    321     }
    322761    else
    323     {
    324         fprintf(stderr, "%s: GetRevision() returned %08x\n",
    325             argv[0], (unsigned)rc);
    326     }
     762        PrintErrorInfo(argv[0], "GetRevision() failed", rc);
    327763
    328764    /* 2. Version */
     
    338774    }
    339775    else
    340     {
    341         fprintf(stderr, "%s: GetVersion() returned %08x\n",
    342             argv[0], (unsigned)rc);
    343     }
     776        PrintErrorInfo(argv[0], "GetVersion() failed", rc);
    344777
    345778    /* 3. Home Folder */
     
    355788    }
    356789    else
    357     {
    358         fprintf(stderr, "%s: GetHomeFolder() returned %08x\n",
    359             argv[0], (unsigned)rc);
    360     }
    361 
    362     listVMs(vbox, session);
     790        PrintErrorInfo(argv[0], "GetHomeFolder() failed", rc);
     791
     792    listVMs(argv[0], vbox, session, queue);
    363793    session->vtbl->UnlockMachine(session);
    364794
     
    369799     */
    370800
    371     g_pVBoxFuncs->pfnComUninitialize();
     801    if (session)
     802    {
     803        session->vtbl->nsisupports.Release((nsISupports *)session);
     804        session = NULL;
     805    }
     806    if (vbox)
     807    {
     808        vbox->vtbl->nsisupports.Release((nsISupports *)vbox);
     809        vbox = NULL;
     810    }
     811    if (vboxclient)
     812    {
     813        vboxclient->vtbl->nsisupports.Release((nsISupports *)vboxclient);
     814        vboxclient = NULL;
     815    }
     816    g_pVBoxFuncs->pfnClientUninitialize();
    372817    VBoxCGlueTerm();
    373     printf("Finished Main\n");
     818    printf("Finished main()\n");
    374819
    375820    return 0;
  • trunk/src/VBox/Main/cbinding/xpcidl.xsl

    r43103 r49539  
    66 *  from the generic interface definition expressed in XML.
    77
    8     Copyright (C) 2008-2012 Oracle Corporation
     8    Copyright (C) 2008-2013 Oracle Corporation
    99
    1010    This file is part of VirtualBox Open Source Edition (OSE), as
     
    10081008    unsigned uVersion;
    10091009
     1010    /** Gets the VirtualBox version, major * 1000000 + minor * 1000 + patch. */
    10101011    unsigned int (*pfnGetVersion)(void);
    10111012
     1013    /** Gets the VirtualBox API version, major * 1000 + minor, e.g. 4003. */
     1014    unsigned int (*pfnGetAPIVersion)(void);
     1015
     1016    /**
     1017     * New and preferred way to initialize the C bindings for an API client.
     1018     *
     1019     * This way is much more flexible, as it can easily handle multiple
     1020     * sessions (important with more complicated API clients, including
     1021     * multithreaded ones), and even VBoxSVC crashes can be detected and
     1022     * processed appropriately by listening for events from the associated
     1023     * event source in VirtualBoxClient. It is completely up to the client
     1024     * to decide what to do (terminate or continue after getting new
     1025     * object references to server-side objects). Must be called in the
     1026     * primary thread of the client, later API use can be done in any
     1027     * thread.
     1028     *
     1029     * Note that the returned reference is owned by the caller, and thus it's
     1030     * the caller's responsibility to handle the reference count appropriately.
     1031     *
     1032     * @param pszVirtualBoxClientIID    pass IVIRTUALBOXCLIENT_IID_STR
     1033     * @param ppVirtualBoxClient        output parameter for VirtualBoxClient
     1034     *              reference, handled as usual with XPCOM.
     1035     * @returns XPCOM error code
     1036     */
     1037    nsresult (*pfnClientInitialize)(const char *pszVirtualBoxClientIID,
     1038                                    IVirtualBoxClient **ppVirtualBoxClient);
     1039    /**
     1040     * Uninitialize the C bindings for an API client.
     1041     *
     1042     * Should be called when the API client is about to terminate and does
     1043     * not want to use the C bindings any more. It will invalidate all
     1044     * object references. It is possible, however, to change one's mind,
     1045     * and call pfnClientInitialize again to continue using the API, as long
     1046     * as none of the object references from before the re-initialization
     1047     * are used. Must be called from the primary thread of the client.
     1048     */
     1049    void (*pfnClientUninitialize)(void);
     1050
     1051    /**
     1052     * Deprecated way to initialize the C bindings and getting important
     1053     * object references. Kept for backwards compatibility.
     1054     *
     1055     * If any returned reference is NULL then the initialization failed.
     1056     * Note that the returned references are owned by the C bindings. The
     1057     * number of calls to Release in the client code must match the number
     1058     * of calls to AddRef, and additionally at no point in time there can
     1059     * be more Release calls than AddRef calls.
     1060     *
     1061     * @param pszVirtualBoxIID      pass IVIRTUALBOX_IID_STR
     1062     * @param ppVirtualBox          output parameter for VirtualBox reference,
     1063     *          owned by C bindings
     1064     * @param pszSessionIID         pass ISESSION_IID_STR
     1065     * @param ppSession             output parameter for Session reference,
     1066     *          owned by C bindings
     1067     */
    10121068    void  (*pfnComInitialize)(const char *pszVirtualBoxIID,
    10131069                              IVirtualBox **ppVirtualBox,
    10141070                              const char *pszSessionIID,
    10151071                              ISession **ppSession);
     1072    /**
     1073     * Deprecated way to uninitialize the C bindings for an API client.
     1074     * Kept for backwards compatibility and must be used if the C bindings
     1075     * were initialized using pfnComInitialize. */
    10161076    void (*pfnComUninitialize)(void);
    10171077
     1078    /**
     1079     * Free memory managed by XPCOM.
     1080     *
     1081     * @param pv        pointer to memory block to be freed
     1082     */
    10181083    void  (*pfnComUnallocMem)(void *pv);
     1084
     1085    /**
     1086     * Convert string from UTF-16 encoding to UTF-8 encoding.
     1087     *
     1088     * @param pwszString    input string
     1089     * @param ppszString    output string
     1090     * @returns IPRT status code
     1091     */
     1092    int   (*pfnUtf16ToUtf8)(const PRUnichar *pwszString, char **ppszString);
     1093    /**
     1094     * Convert string from UTF-8 encoding to UTF-16 encoding.
     1095     *
     1096     * @param pszString     input string
     1097     * @param ppwszString   output string
     1098     * @returns IPRT status code
     1099     */
     1100    int   (*pfnUtf8ToUtf16)(const char *pszString, PRUnichar **ppwszString);
     1101    /**
     1102     * Free memory returned by pfnUtf16ToUtf8. Do not use for anything else.
     1103     *
     1104     * @param pszString     string to be freed.
     1105     */
     1106    void  (*pfnUtf8Free)(char *pszString);
     1107    /**
     1108     * Free memory returned by pfnUtf8ToUtf16. Do not use for anything else.
     1109     *
     1110     * @param pwszString    string to be freed.
     1111     */
    10191112    void  (*pfnUtf16Free)(PRUnichar *pwszString);
    1020     void  (*pfnUtf8Free)(char *pszString);
    1021 
    1022     int   (*pfnUtf16ToUtf8)(const PRUnichar *pwszString, char **ppszString);
    1023     int   (*pfnUtf8ToUtf16)(const char *pszString, PRUnichar **ppwszString);
    1024 
    1025     void  (*pfnGetEventQueue)(nsIEventQueue **eventQueue);
     1113
     1114    /**
     1115     * Get main XPCOM event queue.
     1116     *
     1117     * @param ppEventQueue      output parameter for nsIEventQueue reference,
     1118     *              owned by C bindings.
     1119     */
     1120    void  (*pfnGetEventQueue)(nsIEventQueue **ppEventQueue);
     1121
     1122    /**
     1123     * Get current XPCOM exception.
     1124     *
     1125     * @param ppException       output parameter for nsIException reference,
     1126     *              may be @c NULL if no exception object has been created by
     1127     *              a previous XPCOM call.
     1128     * @returns XPCOM error code
     1129     */
     1130    nsresult (*pfnGetException)(nsIException **ppException);
     1131    /**
     1132     * Clears current XPCOM exception.
     1133     *
     1134     * @returns XPCOM error code
     1135     */
     1136    nsresult (*pfnClearException)(void);
    10261137
    10271138    /** Tail version, same as uVersion. */
     
    10341145 * For use with VBoxGetXPCOMCFunctions and to be found in
    10351146 * VBOXXPCOMC::uVersion. */
    1036 #define VBOX_XPCOMC_VERSION     0x00020000U
     1147#define VBOX_XPCOMC_VERSION     0x00030000U
    10371148
    10381149VBOXXPCOMC_DECL(PCVBOXXPCOM) VBoxGetXPCOMCFunctions(unsigned uVersion);
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette