VirtualBox

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

Last change on this file since 55437 was 54027, checked in by vboxsync, 10 years ago

Main/cbinding: Add new helper functions to clear out strings (useful if they contain sensitive data). While doing this, added code to the glue init which checks if the version of the structure is compatible with what the client expects. This exposed annoying code duplication between the non-Windows/Windows implementations which is now eliminated.

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