VirtualBox

source: vbox/trunk/src/VBox/Main/cbinding/VBoxCAPI.cpp@ 50295

Last change on this file since 50295 was 50183, checked in by vboxsync, 11 years ago

Main/cbinding: bring the C binding to a new functionality level, making them handle both COM and XPCOM based platforms, plus some xsl cleanup to eliminate the $dispatch case which was unused for many years (and will not be used again)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 22.4 KB
Line 
1/* $Id: VBoxCAPI.cpp 50183 2014-01-23 15:58:21Z vboxsync $ */
2/** @file VBoxCAPI.cpp
3 * Utility functions to use with the C API binding.
4 */
5
6/*
7 * Copyright (C) 2009-2014 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18#define LOG_GROUP LOG_GROUP_MAIN
19
20#include "VBoxCAPI.h"
21
22#ifdef VBOX_WITH_XPCOM
23# include <nsMemory.h>
24# include <nsIServiceManager.h>
25# include <nsEventQueueUtils.h>
26# include <nsIExceptionService.h>
27# include <stdlib.h>
28#endif /* VBOX_WITH_XPCOM */
29
30#include <iprt/initterm.h>
31#include <iprt/string.h>
32#include <iprt/uuid.h>
33#include <iprt/env.h>
34#include <iprt/mem.h>
35#include <VBox/log.h>
36#include <VBox/version.h>
37
38#include "VBox/com/com.h"
39#include "VBox/com/NativeEventQueue.h"
40
41using namespace std;
42
43/* The following 2 object references should be eliminated once the legacy
44 * way to initialize the COM/XPCOM C bindings is removed. */
45static ISession *g_Session = NULL;
46static IVirtualBox *g_VirtualBox = NULL;
47
48#ifdef VBOX_WITH_XPCOM
49/* This object reference should be eliminated once the legacy way of handling
50 * the event queue (XPCOM specific) is removed. */
51static nsIEventQueue *g_EventQueue = NULL;
52#endif /* VBOX_WITH_XPCOM */
53
54static void VBoxComUninitialize(void);
55static void VBoxClientUninitialize(void);
56
57static int
58VBoxUtf16ToUtf8(CBSTR pwszString, char **ppszString)
59{
60 if (!pwszString)
61 {
62 *ppszString = NULL;
63 return VINF_SUCCESS;
64 }
65 return RTUtf16ToUtf8(pwszString, ppszString);
66}
67
68static int
69VBoxUtf8ToUtf16(const char *pszString, BSTR *ppwszString)
70{
71 if (!pszString)
72 {
73 *ppwszString = NULL;
74 return VINF_SUCCESS;
75 }
76#ifdef VBOX_WITH_XPCOM
77 return RTStrToUtf16(pszString, ppwszString);
78#else /* !VBOX_WITH_XPCOM */
79 PRTUTF16 pwsz;
80 int vrc = RTStrToUtf16(pszString, &pwsz);
81 *ppwszString = ::SysAllocString(pwsz);
82 RTUtf16Free(pwsz);
83 return vrc;
84#endif /* !VBOX_WITH_XPCOM */
85}
86
87static void
88VBoxUtf16Free(BSTR pwszString)
89{
90#ifdef VBOX_WITH_XPCOM
91 RTUtf16Free(pwszString);
92#else /* !VBOX_WITH_XPCOM */
93 ::SysFreeString(pwszString);
94#endif /* !VBOX_WITH_XPCOM */
95}
96
97static void
98VBoxUtf8Free(char *pszString)
99{
100 RTStrFree(pszString);
101}
102
103static void
104VBoxComUnallocString(BSTR pwsz)
105{
106 if (pwsz)
107 {
108#ifdef VBOX_WITH_XPCOM
109 nsMemory::Free(pwsz);
110#else /* !VBOX_WITH_XPCOM */
111 ::SysFreeString(pwsz);
112#endif /* !VBOX_WITH_XPCOM */
113 }
114}
115
116static void
117VBoxComUnallocMem(void *pv)
118{
119 VBoxComUnallocString((BSTR)pv);
120}
121
122static ULONG
123VBoxVTElemSize(VARTYPE vt)
124{
125 switch (vt)
126 {
127 case VT_BOOL:
128 case VT_I1:
129 case VT_UI1:
130 return 1;
131 case VT_I2:
132 case VT_UI2:
133 return 2;
134 case VT_I4:
135 case VT_UI4:
136 case VT_HRESULT:
137 return 4;
138 case VT_I8:
139 case VT_UI8:
140 return 8;
141 case VT_BSTR:
142 case VT_DISPATCH:
143 case VT_UNKNOWN:
144 return sizeof(void *);
145 default:
146 return 0;
147 }
148}
149
150static SAFEARRAY *
151VBoxSafeArrayCreateVector(VARTYPE vt, LONG lLbound, ULONG cElements)
152{
153#ifdef VBOX_WITH_XPCOM
154 NOREF(lLbound);
155 ULONG cbElement = VBoxVTElemSize(vt);
156 if (!cbElement)
157 return NULL;
158 SAFEARRAY *psa = (SAFEARRAY *)RTMemAllocZ(sizeof(SAFEARRAY));
159 if (!psa)
160 return psa;
161 if (cElements)
162 {
163 void *pv = nsMemory::Alloc(cElements * cbElement);
164 if (!pv)
165 {
166 RTMemFree(psa);
167 return NULL;
168 }
169 psa->pv = pv;
170 psa->c = cElements;
171 }
172 return psa;
173#else /* !VBOX_WITH_XPCOM */
174 return SafeArrayCreateVector(vt, lLbound, cElements);
175#endif /* !VBOX_WITH_XPCOM */
176}
177
178static SAFEARRAY *
179VBoxSafeArrayOutParamAlloc(void)
180{
181#ifdef VBOX_WITH_XPCOM
182 return (SAFEARRAY *)RTMemAllocZ(sizeof(SAFEARRAY));
183#else /* !VBOX_WITH_XPCOM */
184 return NULL;
185#endif /* !VBOX_WITH_XPCOM */
186}
187
188static HRESULT
189VBoxSafeArrayDestroy(SAFEARRAY *psa)
190{
191#ifdef VBOX_WITH_XPCOM
192 if (psa)
193 {
194 if (psa->pv)
195 nsMemory::Free(psa->pv);
196 RTMemFree(psa);
197 }
198 return S_OK;
199#else /* !VBOX_WITH_XPCOM */
200 return SafeArrayDestroy(psa);
201#endif /* !VBOX_WITH_XPCOM */
202}
203
204static HRESULT
205VBoxSafeArrayCopyInParamHelper(SAFEARRAY *psa, const void *pv, ULONG cb)
206{
207 if (!pv || !psa)
208 return E_POINTER;
209 if (!cb)
210 return S_OK;
211
212 void *pData;
213#ifdef VBOX_WITH_XPCOM
214 pData = psa->pv;
215#else /* !VBOX_WITH_XPCOM */
216 HRESULT rc = SafeArrayAccessData(psa, &pData);
217 if (FAILED(rc))
218 return rc;
219#endif /* !VBOX_WITH_XPCOM */
220 memcpy(pData, pv, cb);
221#ifndef VBOX_WITH_XPCOM
222 SafeArrayUnaccessData(psa);
223#endif /* !VBOX_WITH_XPCOM */
224 return S_OK;
225}
226
227static HRESULT
228VBoxSafeArrayCopyOutParamHelper(void **ppv, ULONG *pcb, VARTYPE vt, SAFEARRAY *psa)
229{
230 if (!ppv)
231 return E_POINTER;
232 ULONG cbElement = VBoxVTElemSize(vt);
233 if (!cbElement)
234 return E_INVALIDARG;
235#ifndef VBOX_WITH_XPCOM
236 if (psa->cDims != 1)
237 return E_INVALIDARG;
238 Assert(cbElement = psa->cbElements);
239#endif /* !VBOX_WITH_XPCOM */
240 void *pData;
241 ULONG cElements;
242#ifdef VBOX_WITH_XPCOM
243 pData = psa->pv;
244 cElements = psa->c;
245#else /* !VBOX_WITH_XPCOM */
246 HRESULT rc = SafeArrayAccessData(psa, &pData);
247 if (FAILED(rc))
248 return rc;
249 cElements = psa->rgsabound[0].cElements;
250#endif /* !VBOX_WITH_XPCOM */
251 size_t cbTotal = cbElement * cElements;
252 void *pv = malloc(cbTotal);
253 if (pv)
254 {
255 memcpy(pv, pData, cbTotal);
256 *ppv = pv;
257 if (pcb)
258 *pcb = (ULONG)cbTotal;
259 }
260#ifndef VBOX_WITH_XPCOM
261 SafeArrayUnaccessData(psa);
262#endif /* !VBOX_WITH_XPCOM */
263 return S_OK;
264}
265
266static HRESULT
267VBoxSafeArrayCopyOutIfaceParamHelper(IUnknown ***ppaObj, ULONG *pcObj, SAFEARRAY *psa)
268{
269 ULONG mypcb;
270 HRESULT rc = VBoxSafeArrayCopyOutParamHelper((void **)ppaObj, &mypcb, VT_UNKNOWN, psa);
271 if (FAILED(rc))
272 return rc;
273 ULONG cElements = mypcb / sizeof(void *);
274 if (pcObj)
275 *pcObj = cElements;
276#ifndef VBOX_WITH_XPCOM
277 /* Do this only for COM, as there the SAFEARRAY destruction will release
278 * the contained references automatically. XPCOM doesn't do that, which
279 * means that copying implicitly transfers ownership. */
280 IUnknown **paObj = *ppaObj;
281 for (ULONG i = 0; i < cElements; i++)
282 {
283 IUnknown *pObj = paObj[i];
284 if (pObj)
285 pObj->AddRef();
286 }
287#endif /* VBOX_WITH_XPCOM */
288 return S_OK;
289}
290
291static void
292VBoxComInitialize(const char *pszVirtualBoxIID, IVirtualBox **ppVirtualBox,
293 const char *pszSessionIID, ISession **ppSession)
294{
295 int vrc;
296 IID virtualBoxIID;
297 IID sessionIID;
298
299 *ppSession = NULL;
300 *ppVirtualBox = NULL;
301
302 /* convert the string representation of the UUIDs (if provided) to IID */
303 if (pszVirtualBoxIID && *pszVirtualBoxIID)
304 {
305 vrc = ::RTUuidFromStr((RTUUID *)&virtualBoxIID, pszVirtualBoxIID);
306 if (RT_FAILURE(vrc))
307 return;
308 }
309 else
310 virtualBoxIID = IID_IVirtualBox;
311 if (pszSessionIID && *pszSessionIID)
312 {
313 vrc = ::RTUuidFromStr((RTUUID *)&sessionIID, pszSessionIID);
314 if (RT_FAILURE(vrc))
315 return;
316 }
317 else
318 sessionIID = IID_ISession;
319
320 HRESULT rc = com::Initialize();
321 if (FAILED(rc))
322 {
323 Log(("Cbinding: COM/XPCOM could not be initialized! rc=%Rhrc\n", rc));
324 VBoxComUninitialize();
325 return;
326 }
327
328#ifdef VBOX_WITH_XPCOM
329 rc = NS_GetMainEventQ(&g_EventQueue);
330 if (FAILED(rc))
331 {
332 Log(("Cbinding: Could not get XPCOM event queue! rc=%Rhrc\n", rc));
333 VBoxComUninitialize();
334 return;
335 }
336#endif /* VBOX_WITH_XPCOM */
337
338#ifdef VBOX_WITH_XPCOM
339 nsIComponentManager *pManager;
340 rc = NS_GetComponentManager(&pManager);
341 if (FAILED(rc))
342 {
343 Log(("Cbinding: Could not get component manager! rc=%Rhrc\n", rc));
344 VBoxComUninitialize();
345 return;
346 }
347
348 rc = pManager->CreateInstanceByContractID(NS_VIRTUALBOX_CONTRACTID,
349 nsnull,
350 virtualBoxIID,
351 (void **)&g_VirtualBox);
352#else /* !VBOX_WITH_XPCOM */
353 rc = CoCreateInstance(CLSID_VirtualBox, NULL, CLSCTX_LOCAL_SERVER, virtualBoxIID, (void **)&g_VirtualBox);
354#endif /* !VBOX_WITH_XPCOM */
355 if (FAILED(rc))
356 {
357 Log(("Cbinding: Could not instantiate VirtualBox object! rc=%Rhrc\n",rc));
358#ifdef VBOX_WITH_XPCOM
359 pManager->Release();
360 pManager = NULL;
361#endif /* VBOX_WITH_XPCOM */
362 VBoxComUninitialize();
363 return;
364 }
365
366 Log(("Cbinding: IVirtualBox object created.\n"));
367
368#ifdef VBOX_WITH_XPCOM
369 rc = pManager->CreateInstanceByContractID(NS_SESSION_CONTRACTID,
370 nsnull,
371 sessionIID,
372 (void **)&g_Session);
373#else /* !VBOX_WITH_XPCOM */
374 rc = CoCreateInstance(CLSID_Session, NULL, CLSCTX_INPROC_SERVER, sessionIID, (void **)&g_Session);
375#endif /* !VBOX_WITH_XPCOM */
376 if (FAILED(rc))
377 {
378 Log(("Cbinding: Could not instantiate Session object! rc=%Rhrc\n",rc));
379#ifdef VBOX_WITH_XPCOM
380 pManager->Release();
381 pManager = NULL;
382#endif /* VBOX_WITH_XPCOM */
383 VBoxComUninitialize();
384 return;
385 }
386
387 Log(("Cbinding: ISession object created.\n"));
388
389#ifdef VBOX_WITH_XPCOM
390 pManager->Release();
391 pManager = NULL;
392#endif /* VBOX_WITH_XPCOM */
393
394 *ppSession = g_Session;
395 *ppVirtualBox = g_VirtualBox;
396}
397
398static void
399VBoxComInitializeV1(IVirtualBox **ppVirtualBox, ISession **ppSession)
400{
401 VBoxComInitialize(NULL, ppVirtualBox, NULL, ppSession);
402}
403
404static void
405VBoxComUninitialize(void)
406{
407 if (g_Session)
408 {
409 g_Session->Release();
410 g_Session = NULL;
411 }
412 if (g_VirtualBox)
413 {
414 g_VirtualBox->Release();
415 g_VirtualBox = NULL;
416 }
417#ifdef VBOX_WITH_XPCOM
418 if (g_EventQueue)
419 {
420 g_EventQueue->Release();
421 g_EventQueue = NULL;
422 }
423#endif /* VBOX_WITH_XPCOM */
424 com::Shutdown();
425 Log(("Cbinding: Cleaned up the created objects.\n"));
426}
427
428#ifdef VBOX_WITH_XPCOM
429static void
430VBoxGetEventQueue(nsIEventQueue **ppEventQueue)
431{
432 *ppEventQueue = g_EventQueue;
433}
434#endif /* VBOX_WITH_XPCOM */
435
436static int
437VBoxProcessEventQueue(LONG64 iTimeoutMS)
438{
439 RTMSINTERVAL iTimeout;
440 if (iTimeoutMS < 0 || iTimeoutMS > UINT32_MAX)
441 iTimeout = RT_INDEFINITE_WAIT;
442 else
443 iTimeout = (RTMSINTERVAL)iTimeoutMS;
444 int vrc = com::NativeEventQueue::getMainEventQueue()->processEventQueue(iTimeout);
445 switch (vrc)
446 {
447 case VINF_SUCCESS:
448 return 0;
449 case VINF_INTERRUPTED:
450 return 1;
451 case VERR_INTERRUPTED:
452 return 2;
453 case VERR_TIMEOUT:
454 return 3;
455 case VERR_INVALID_CONTEXT:
456 return 4;
457 default:
458 return 5;
459 }
460}
461
462static int
463VBoxInterruptEventQueueProcessing(void)
464{
465 com::NativeEventQueue::getMainEventQueue()->interruptEventQueueProcessing();
466 return 0;
467}
468
469static HRESULT
470VBoxGetException(IErrorInfo **ppException)
471{
472 HRESULT rc;
473
474 *ppException = NULL;
475
476#ifdef VBOX_WITH_XPCOM
477 nsIServiceManager *mgr = NULL;
478 rc = NS_GetServiceManager(&mgr);
479 if (FAILED(rc) || !mgr)
480 return rc;
481
482 IID esid = NS_IEXCEPTIONSERVICE_IID;
483 nsIExceptionService *es = NULL;
484 rc = mgr->GetServiceByContractID(NS_EXCEPTIONSERVICE_CONTRACTID, esid, (void **)&es);
485 if (FAILED(rc) || !es)
486 {
487 mgr->Release();
488 return rc;
489 }
490
491 nsIExceptionManager *em;
492 rc = es->GetCurrentExceptionManager(&em);
493 if (FAILED(rc) || !em)
494 {
495 es->Release();
496 mgr->Release();
497 return rc;
498 }
499
500 nsIException *ex;
501 rc = em->GetCurrentException(&ex);
502 if (FAILED(rc))
503 {
504 em->Release();
505 es->Release();
506 mgr->Release();
507 return rc;
508 }
509
510 *ppException = ex;
511 em->Release();
512 es->Release();
513 mgr->Release();
514#else /* !VBOX_WITH_XPCOM */
515 IErrorInfo *ex;
516 rc = ::GetErrorInfo(0, &ex);
517 if (FAILED(rc))
518 return rc;
519
520 *ppException = ex;
521#endif /* !VBOX_WITH_XPCOM */
522
523 return rc;
524}
525
526static HRESULT
527VBoxClearException(void)
528{
529 HRESULT rc;
530
531#ifdef VBOX_WITH_XPCOM
532 nsIServiceManager *mgr = NULL;
533 rc = NS_GetServiceManager(&mgr);
534 if (FAILED(rc) || !mgr)
535 return rc;
536
537 IID esid = NS_IEXCEPTIONSERVICE_IID;
538 nsIExceptionService *es = NULL;
539 rc = mgr->GetServiceByContractID(NS_EXCEPTIONSERVICE_CONTRACTID, esid, (void **)&es);
540 if (FAILED(rc) || !es)
541 {
542 mgr->Release();
543 return rc;
544 }
545
546 nsIExceptionManager *em;
547 rc = es->GetCurrentExceptionManager(&em);
548 if (FAILED(rc) || !em)
549 {
550 es->Release();
551 mgr->Release();
552 return rc;
553 }
554
555 rc = em->SetCurrentException(NULL);
556 em->Release();
557 es->Release();
558 mgr->Release();
559#else /* !VBOX_WITH_XPCOM */
560 rc = ::SetErrorInfo(0, NULL);
561#endif /* !VBOX_WITH_XPCOM */
562
563 return rc;
564}
565
566static HRESULT
567VBoxClientInitialize(const char *pszVirtualBoxClientIID, IVirtualBoxClient **ppVirtualBoxClient)
568{
569 IID virtualBoxClientIID;
570
571 *ppVirtualBoxClient = NULL;
572
573 /* convert the string representation of UUID to IID type */
574 if (pszVirtualBoxClientIID && *pszVirtualBoxClientIID)
575 {
576 int vrc = ::RTUuidFromStr((RTUUID *)&virtualBoxClientIID, pszVirtualBoxClientIID);
577 if (RT_FAILURE(vrc))
578 return E_INVALIDARG;
579 }
580 else
581 virtualBoxClientIID = IID_IVirtualBoxClient;
582
583 HRESULT rc = com::Initialize();
584 if (FAILED(rc))
585 {
586 Log(("Cbinding: COM/XPCOM could not be initialized! rc=%Rhrc\n", rc));
587 VBoxClientUninitialize();
588 return rc;
589 }
590
591#ifdef VBOX_WITH_XPCOM
592 rc = NS_GetMainEventQ(&g_EventQueue);
593 if (NS_FAILED(rc))
594 {
595 Log(("Cbinding: Could not get XPCOM event queue! rc=%Rhrc\n", rc));
596 VBoxClientUninitialize();
597 return rc;
598 }
599#endif /* VBOX_WITH_XPCOM */
600
601#ifdef VBOX_WITH_XPCOM
602 nsIComponentManager *pManager;
603 rc = NS_GetComponentManager(&pManager);
604 if (FAILED(rc))
605 {
606 Log(("Cbinding: Could not get component manager! rc=%Rhrc\n", rc));
607 VBoxClientUninitialize();
608 return rc;
609 }
610
611 rc = pManager->CreateInstanceByContractID(NS_VIRTUALBOXCLIENT_CONTRACTID,
612 nsnull,
613 virtualBoxClientIID,
614 (void **)ppVirtualBoxClient);
615#else /* !VBOX_WITH_XPCOM */
616 rc = CoCreateInstance(CLSID_VirtualBoxClient, NULL, CLSCTX_INPROC_SERVER, virtualBoxClientIID, (void **)ppVirtualBoxClient);
617#endif /* !VBOX_WITH_XPCOM */
618 if (FAILED(rc))
619 {
620 Log(("Cbinding: Could not instantiate VirtualBoxClient object! rc=%Rhrc\n",rc));
621#ifdef VBOX_WITH_XPCOM
622 pManager->Release();
623 pManager = NULL;
624#endif /* VBOX_WITH_XPCOM */
625 VBoxClientUninitialize();
626 return rc;
627 }
628
629#ifdef VBOX_WITH_XPCOM
630 pManager->Release();
631 pManager = NULL;
632#endif /* VBOX_WITH_XPCOM */
633
634 Log(("Cbinding: IVirtualBoxClient object created.\n"));
635
636 return S_OK;
637}
638
639static HRESULT
640VBoxClientThreadInitialize(void)
641{
642 return com::Initialize();
643}
644
645static HRESULT
646VBoxClientThreadUninitialize(void)
647{
648 return com::Shutdown();
649}
650
651static void
652VBoxClientUninitialize(void)
653{
654#ifdef VBOX_WITH_XPCOM
655 if (g_EventQueue)
656 {
657 NS_RELEASE(g_EventQueue);
658 g_EventQueue = NULL;
659 }
660#endif /* VBOX_WITH_XPCOM */
661 com::Shutdown();
662 Log(("Cbinding: Cleaned up the created objects.\n"));
663}
664
665static unsigned int
666VBoxVersion(void)
667{
668 return VBOX_VERSION_MAJOR * 1000 * 1000 + VBOX_VERSION_MINOR * 1000 + VBOX_VERSION_BUILD;
669}
670
671static unsigned int
672VBoxAPIVersion(void)
673{
674 return VBOX_VERSION_MAJOR * 1000 + VBOX_VERSION_MINOR + (VBOX_VERSION_BUILD > 50 ? 1 : 0);
675}
676
677VBOXCAPI_DECL(PCVBOXCAPI)
678VBoxGetCAPIFunctions(unsigned uVersion)
679{
680 /* This is the first piece of code which knows that IPRT exists, so
681 * initialize it properly. The limited initialization in VBoxC is not
682 * sufficient, and causes trouble with com::Initialize() misbehaving. */
683 RTR3InitDll(0);
684
685 /*
686 * The current interface version.
687 */
688 static const VBOXCAPI s_Functions =
689 {
690 sizeof(VBOXCAPI),
691 VBOX_CAPI_VERSION,
692
693 VBoxVersion,
694 VBoxAPIVersion,
695
696 VBoxClientInitialize,
697 VBoxClientThreadInitialize,
698 VBoxClientThreadUninitialize,
699 VBoxClientUninitialize,
700
701 VBoxComInitialize,
702 VBoxComUninitialize,
703
704 VBoxComUnallocString,
705
706 VBoxUtf16ToUtf8,
707 VBoxUtf8ToUtf16,
708 VBoxUtf8Free,
709 VBoxUtf16Free,
710
711 VBoxSafeArrayCreateVector,
712 VBoxSafeArrayOutParamAlloc,
713 VBoxSafeArrayCopyInParamHelper,
714 VBoxSafeArrayCopyOutParamHelper,
715 VBoxSafeArrayCopyOutIfaceParamHelper,
716 VBoxSafeArrayDestroy,
717
718#ifdef VBOX_WITH_XPCOM
719 VBoxGetEventQueue,
720#endif /* VBOX_WITH_XPCOM */
721 VBoxGetException,
722 VBoxClearException,
723 VBoxProcessEventQueue,
724 VBoxInterruptEventQueueProcessing,
725
726 VBOX_CAPI_VERSION
727 };
728
729 if ((uVersion & 0xffff0000U) == (VBOX_CAPI_VERSION & 0xffff0000U))
730 return &s_Functions;
731
732 /*
733 * Legacy interface version 3.0.
734 */
735 static const struct VBOXCAPIV3
736 {
737 /** The size of the structure. */
738 unsigned cb;
739 /** The structure version. */
740 unsigned uVersion;
741
742 unsigned int (*pfnGetVersion)(void);
743
744 unsigned int (*pfnGetAPIVersion)(void);
745
746 HRESULT (*pfnClientInitialize)(const char *pszVirtualBoxClientIID,
747 IVirtualBoxClient **ppVirtualBoxClient);
748 void (*pfnClientUninitialize)(void);
749
750 void (*pfnComInitialize)(const char *pszVirtualBoxIID,
751 IVirtualBox **ppVirtualBox,
752 const char *pszSessionIID,
753 ISession **ppSession);
754
755 void (*pfnComUninitialize)(void);
756
757 void (*pfnComUnallocMem)(void *pv);
758
759 int (*pfnUtf16ToUtf8)(CBSTR pwszString, char **ppszString);
760 int (*pfnUtf8ToUtf16)(const char *pszString, BSTR *ppwszString);
761 void (*pfnUtf8Free)(char *pszString);
762 void (*pfnUtf16Free)(BSTR pwszString);
763
764#ifdef VBOX_WITH_XPCOM
765 void (*pfnGetEventQueue)(nsIEventQueue **ppEventQueue);
766#endif /* VBOX_WITH_XPCOM */
767 HRESULT (*pfnGetException)(IErrorInfo **ppException);
768 HRESULT (*pfnClearException)(void);
769
770 /** Tail version, same as uVersion. */
771 unsigned uEndVersion;
772 } s_Functions_v3_0 =
773 {
774 sizeof(s_Functions_v3_0),
775 0x00030000U,
776
777 VBoxVersion,
778 VBoxAPIVersion,
779
780 VBoxClientInitialize,
781 VBoxClientUninitialize,
782
783 VBoxComInitialize,
784 VBoxComUninitialize,
785
786 VBoxComUnallocMem,
787
788 VBoxUtf16ToUtf8,
789 VBoxUtf8ToUtf16,
790 VBoxUtf8Free,
791 VBoxUtf16Free,
792
793#ifdef VBOX_WITH_XPCOM
794 VBoxGetEventQueue,
795#endif /* VBOX_WITH_XPCOM */
796 VBoxGetException,
797 VBoxClearException,
798
799 0x00030000U
800 };
801
802 if ((uVersion & 0xffff0000U) == 0x00030000U)
803 return (PCVBOXCAPI)&s_Functions_v3_0;
804
805 /*
806 * Legacy interface version 2.0.
807 */
808 static const struct VBOXCAPIV2
809 {
810 /** The size of the structure. */
811 unsigned cb;
812 /** The structure version. */
813 unsigned uVersion;
814
815 unsigned int (*pfnGetVersion)(void);
816
817 void (*pfnComInitialize)(const char *pszVirtualBoxIID,
818 IVirtualBox **ppVirtualBox,
819 const char *pszSessionIID,
820 ISession **ppSession);
821
822 void (*pfnComUninitialize)(void);
823
824 void (*pfnComUnallocMem)(void *pv);
825 void (*pfnUtf16Free)(BSTR pwszString);
826 void (*pfnUtf8Free)(char *pszString);
827
828 int (*pfnUtf16ToUtf8)(CBSTR pwszString, char **ppszString);
829 int (*pfnUtf8ToUtf16)(const char *pszString, BSTR *ppwszString);
830
831#ifdef VBOX_WITH_XPCOM
832 void (*pfnGetEventQueue)(nsIEventQueue **ppEventQueue);
833#endif /* VBOX_WITH_XPCOM */
834
835 /** Tail version, same as uVersion. */
836 unsigned uEndVersion;
837 } s_Functions_v2_0 =
838 {
839 sizeof(s_Functions_v2_0),
840 0x00020000U,
841
842 VBoxVersion,
843
844 VBoxComInitialize,
845 VBoxComUninitialize,
846
847 VBoxComUnallocMem,
848 VBoxUtf16Free,
849 VBoxUtf8Free,
850
851 VBoxUtf16ToUtf8,
852 VBoxUtf8ToUtf16,
853
854#ifdef VBOX_WITH_XPCOM
855 VBoxGetEventQueue,
856#endif /* VBOX_WITH_XPCOM */
857
858 0x00020000U
859 };
860
861 if ((uVersion & 0xffff0000U) == 0x00020000U)
862 return (PCVBOXCAPI)&s_Functions_v2_0;
863
864 /*
865 * Legacy interface version 1.0.
866 */
867 static const struct VBOXCAPIV1
868 {
869 /** The size of the structure. */
870 unsigned cb;
871 /** The structure version. */
872 unsigned uVersion;
873
874 unsigned int (*pfnGetVersion)(void);
875
876 void (*pfnComInitialize)(IVirtualBox **virtualBox, ISession **session);
877 void (*pfnComUninitialize)(void);
878
879 void (*pfnComUnallocMem)(void *pv);
880 void (*pfnUtf16Free)(BSTR pwszString);
881 void (*pfnUtf8Free)(char *pszString);
882
883 int (*pfnUtf16ToUtf8)(CBSTR pwszString, char **ppszString);
884 int (*pfnUtf8ToUtf16)(const char *pszString, BSTR *ppwszString);
885
886 /** Tail version, same as uVersion. */
887 unsigned uEndVersion;
888 } s_Functions_v1_0 =
889 {
890 sizeof(s_Functions_v1_0),
891 0x00010000U,
892
893 VBoxVersion,
894
895 VBoxComInitializeV1,
896 VBoxComUninitialize,
897
898 VBoxComUnallocMem,
899 VBoxUtf16Free,
900 VBoxUtf8Free,
901
902 VBoxUtf16ToUtf8,
903 VBoxUtf8ToUtf16,
904
905 0x00010000U
906 };
907
908 if ((uVersion & 0xffff0000U) == 0x00010000U)
909 return (PCVBOXCAPI)&s_Functions_v1_0;
910
911 /*
912 * Unsupported interface version.
913 */
914 return NULL;
915}
916
917#ifdef VBOX_WITH_XPCOM
918VBOXCAPI_DECL(PCVBOXCAPI)
919VBoxGetXPCOMCFunctions(unsigned uVersion)
920{
921 return VBoxGetCAPIFunctions(uVersion);
922}
923#endif /* VBOX_WITH_XPCOM */
924/* vim: set ts=4 sw=4 et: */
Note: See TracBrowser for help on using the repository browser.

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