Index: /trunk/src/VBox/Main/cbinding/VBoxCAPI.cpp
===================================================================
--- /trunk/src/VBox/Main/cbinding/VBoxCAPI.cpp	(revision 54026)
+++ /trunk/src/VBox/Main/cbinding/VBoxCAPI.cpp	(revision 54027)
@@ -5,5 +5,5 @@
 
 /*
- * Copyright (C) 2009-2014 Oracle Corporation
+ * Copyright (C) 2009-2015 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -83,4 +83,16 @@
     return vrc;
 #endif /* !VBOX_WITH_XPCOM */
+}
+
+static void
+VBoxUtf8Clear(char *pszString)
+{
+    RT_BZERO(pszString, strlen(pszString));
+}
+
+static void
+VBoxUtf16Clear(BSTR pwszString)
+{
+    RT_BZERO(pwszString, RTUtf16Len(pwszString) * sizeof(RTUTF16));
 }
 
@@ -760,4 +772,7 @@
         VBoxInterruptEventQueueProcessing,
 
+        VBoxUtf8Clear,
+        VBoxUtf16Clear,
+
         VBOX_CAPI_VERSION
     };
@@ -767,7 +782,7 @@
 
     /*
-     * Legacy interface version 4.0.
+     * Legacy interface version 3.0.
      */
-    static const struct VBOXCAPIV4
+    static const struct VBOXCAPIV3
     {
         /** The size of the structure. */
@@ -777,47 +792,37 @@
 
         unsigned int (*pfnGetVersion)(void);
+
         unsigned int (*pfnGetAPIVersion)(void);
 
         HRESULT (*pfnClientInitialize)(const char *pszVirtualBoxClientIID,
                                        IVirtualBoxClient **ppVirtualBoxClient);
-        HRESULT (*pfnClientThreadInitialize)(void);
-        HRESULT (*pfnClientThreadUninitialize)(void);
         void (*pfnClientUninitialize)(void);
 
-        void  (*pfnComInitialize)(const char *pszVirtualBoxIID,
-                                  IVirtualBox **ppVirtualBox,
-                                  const char *pszSessionIID,
-                                  ISession **ppSession);
-
-        void  (*pfnComUninitialize)(void);
-
-        void (*pfnComUnallocString)(BSTR pwsz);
-
-        int   (*pfnUtf16ToUtf8)(CBSTR pwszString, char **ppszString);
-        int   (*pfnUtf8ToUtf16)(const char *pszString, BSTR *ppwszString);
-        void  (*pfnUtf8Free)(char *pszString);
-        void  (*pfnUtf16Free)(BSTR pwszString);
-
-        SAFEARRAY *(*pfnSafeArrayCreateVector)(VARTYPE vt, LONG lLbound, ULONG cElements);
-        SAFEARRAY *(*pfnSafeArrayOutParamAlloc)(void);
-        HRESULT (*pfnSafeArrayCopyInParamHelper)(SAFEARRAY *psa, const void *pv, ULONG cb);
-        HRESULT (*pfnSafeArrayCopyOutParamHelper)(void **ppv, ULONG *pcb, VARTYPE vt, SAFEARRAY *psa);
-        HRESULT (*pfnSafeArrayCopyOutIfaceParamHelper)(IUnknown ***ppaObj, ULONG *pcObj, SAFEARRAY *psa);
-        HRESULT (*pfnSafeArrayDestroy)(SAFEARRAY *psa);
-
-#ifdef VBOX_WITH_XPCOM
-        void  (*pfnGetEventQueue)(nsIEventQueue **ppEventQueue);
+        void (*pfnComInitialize)(const char *pszVirtualBoxIID,
+                                 IVirtualBox **ppVirtualBox,
+                                 const char *pszSessionIID,
+                                 ISession **ppSession);
+
+        void (*pfnComUninitialize)(void);
+
+        void (*pfnComUnallocMem)(void *pv);
+
+        int (*pfnUtf16ToUtf8)(CBSTR pwszString, char **ppszString);
+        int (*pfnUtf8ToUtf16)(const char *pszString, BSTR *ppwszString);
+        void (*pfnUtf8Free)(char *pszString);
+        void (*pfnUtf16Free)(BSTR pwszString);
+
+#ifdef VBOX_WITH_XPCOM
+        void (*pfnGetEventQueue)(nsIEventQueue **ppEventQueue);
 #endif /* VBOX_WITH_XPCOM */
         HRESULT (*pfnGetException)(IErrorInfo **ppException);
         HRESULT (*pfnClearException)(void);
-        int (*pfnProcessEventQueue)(LONG64 iTimeoutMS);
-        int (*pfnInterruptEventQueueProcessing)(void);
 
         /** Tail version, same as uVersion. */
         unsigned uEndVersion;
-    } s_Functions_v4_0 =
-    {
-        sizeof(s_Functions_v4_0),
-        0x00040000U,
+    } s_Functions_v3_0 =
+    {
+        sizeof(s_Functions_v3_0),
+        0x00030000U,
 
         VBoxVersion,
@@ -825,6 +830,4 @@
 
         VBoxClientInitialize,
-        VBoxClientThreadInitialize,
-        VBoxClientThreadUninitialize,
         VBoxClientUninitialize,
 
@@ -832,5 +835,5 @@
         VBoxComUninitialize,
 
-        VBoxComUnallocString,
+        VBoxComUnallocMem,
 
         VBoxUtf16ToUtf8,
@@ -839,11 +842,4 @@
         VBoxUtf16Free,
 
-        VBoxSafeArrayCreateVector,
-        VBoxSafeArrayOutParamAlloc,
-        VBoxSafeArrayCopyInParamHelper,
-        VBoxSafeArrayCopyOutParamHelper,
-        VBoxSafeArrayCopyOutIfaceParamHelper,
-        VBoxSafeArrayDestroy,
-
 #ifdef VBOX_WITH_XPCOM
         VBoxGetEventQueue,
@@ -851,17 +847,15 @@
         VBoxGetException,
         VBoxClearException,
-        VBoxProcessEventQueue,
-        VBoxInterruptEventQueueProcessing,
-
-        0x00040000U
+
+        0x00030000U
     };
 
-    if ((uVersion & 0xffff0000U) == 0x00040000U)
-        return (PCVBOXCAPI)&s_Functions_v4_0;
+    if ((uVersion & 0xffff0000U) == 0x00030000U)
+        return (PCVBOXCAPI)&s_Functions_v3_0;
 
     /*
-     * Legacy interface version 3.0.
+     * Legacy interface version 2.0.
      */
-    static const struct VBOXCAPIV3
+    static const struct VBOXCAPIV2
     {
         /** The size of the structure. */
@@ -872,42 +866,30 @@
         unsigned int (*pfnGetVersion)(void);
 
-        unsigned int (*pfnGetAPIVersion)(void);
-
-        HRESULT (*pfnClientInitialize)(const char *pszVirtualBoxClientIID,
-                                       IVirtualBoxClient **ppVirtualBoxClient);
-        void (*pfnClientUninitialize)(void);
-
-        void  (*pfnComInitialize)(const char *pszVirtualBoxIID,
-                                  IVirtualBox **ppVirtualBox,
-                                  const char *pszSessionIID,
-                                  ISession **ppSession);
-
-        void  (*pfnComUninitialize)(void);
-
-        void  (*pfnComUnallocMem)(void *pv);
-
-        int   (*pfnUtf16ToUtf8)(CBSTR pwszString, char **ppszString);
-        int   (*pfnUtf8ToUtf16)(const char *pszString, BSTR *ppwszString);
-        void  (*pfnUtf8Free)(char *pszString);
-        void  (*pfnUtf16Free)(BSTR pwszString);
-
-#ifdef VBOX_WITH_XPCOM
-        void  (*pfnGetEventQueue)(nsIEventQueue **ppEventQueue);
-#endif /* VBOX_WITH_XPCOM */
-        HRESULT (*pfnGetException)(IErrorInfo **ppException);
-        HRESULT (*pfnClearException)(void);
+        void (*pfnComInitialize)(const char *pszVirtualBoxIID,
+                                 IVirtualBox **ppVirtualBox,
+                                 const char *pszSessionIID,
+                                 ISession **ppSession);
+
+        void (*pfnComUninitialize)(void);
+
+        void (*pfnComUnallocMem)(void *pv);
+        void (*pfnUtf16Free)(BSTR pwszString);
+        void (*pfnUtf8Free)(char *pszString);
+
+        int (*pfnUtf16ToUtf8)(CBSTR pwszString, char **ppszString);
+        int (*pfnUtf8ToUtf16)(const char *pszString, BSTR *ppwszString);
+
+#ifdef VBOX_WITH_XPCOM
+        void (*pfnGetEventQueue)(nsIEventQueue **ppEventQueue);
+#endif /* VBOX_WITH_XPCOM */
 
         /** Tail version, same as uVersion. */
         unsigned uEndVersion;
-    } s_Functions_v3_0 =
-    {
-        sizeof(s_Functions_v3_0),
-        0x00030000U,
+    } s_Functions_v2_0 =
+    {
+        sizeof(s_Functions_v2_0),
+        0x00020000U,
 
         VBoxVersion,
-        VBoxAPIVersion,
-
-        VBoxClientInitialize,
-        VBoxClientUninitialize,
 
         VBoxComInitialize,
@@ -915,26 +897,24 @@
 
         VBoxComUnallocMem,
+        VBoxUtf16Free,
+        VBoxUtf8Free,
 
         VBoxUtf16ToUtf8,
         VBoxUtf8ToUtf16,
-        VBoxUtf8Free,
-        VBoxUtf16Free,
 
 #ifdef VBOX_WITH_XPCOM
         VBoxGetEventQueue,
 #endif /* VBOX_WITH_XPCOM */
-        VBoxGetException,
-        VBoxClearException,
-
-        0x00030000U
+
+        0x00020000U
     };
 
-    if ((uVersion & 0xffff0000U) == 0x00030000U)
-        return (PCVBOXCAPI)&s_Functions_v3_0;
+    if ((uVersion & 0xffff0000U) == 0x00020000U)
+        return (PCVBOXCAPI)&s_Functions_v2_0;
 
     /*
-     * Legacy interface version 2.0.
+     * Legacy interface version 1.0.
      */
-    static const struct VBOXCAPIV2
+    static const struct VBOXCAPIV1
     {
         /** The size of the structure. */
@@ -945,72 +925,13 @@
         unsigned int (*pfnGetVersion)(void);
 
-        void  (*pfnComInitialize)(const char *pszVirtualBoxIID,
-                                  IVirtualBox **ppVirtualBox,
-                                  const char *pszSessionIID,
-                                  ISession **ppSession);
-
-        void  (*pfnComUninitialize)(void);
-
-        void  (*pfnComUnallocMem)(void *pv);
-        void  (*pfnUtf16Free)(BSTR pwszString);
-        void  (*pfnUtf8Free)(char *pszString);
-
-        int   (*pfnUtf16ToUtf8)(CBSTR pwszString, char **ppszString);
-        int   (*pfnUtf8ToUtf16)(const char *pszString, BSTR *ppwszString);
-
-#ifdef VBOX_WITH_XPCOM
-        void  (*pfnGetEventQueue)(nsIEventQueue **ppEventQueue);
-#endif /* VBOX_WITH_XPCOM */
-
-        /** Tail version, same as uVersion. */
-        unsigned uEndVersion;
-    } s_Functions_v2_0 =
-    {
-        sizeof(s_Functions_v2_0),
-        0x00020000U,
-
-        VBoxVersion,
-
-        VBoxComInitialize,
-        VBoxComUninitialize,
-
-        VBoxComUnallocMem,
-        VBoxUtf16Free,
-        VBoxUtf8Free,
-
-        VBoxUtf16ToUtf8,
-        VBoxUtf8ToUtf16,
-
-#ifdef VBOX_WITH_XPCOM
-        VBoxGetEventQueue,
-#endif /* VBOX_WITH_XPCOM */
-
-        0x00020000U
-    };
-
-    if ((uVersion & 0xffff0000U) == 0x00020000U)
-        return (PCVBOXCAPI)&s_Functions_v2_0;
-
-    /*
-     * Legacy interface version 1.0.
-     */
-    static const struct VBOXCAPIV1
-    {
-        /** The size of the structure. */
-        unsigned cb;
-        /** The structure version. */
-        unsigned uVersion;
-
-        unsigned int (*pfnGetVersion)(void);
-
-        void  (*pfnComInitialize)(IVirtualBox **virtualBox, ISession **session);
-        void  (*pfnComUninitialize)(void);
-
-        void  (*pfnComUnallocMem)(void *pv);
-        void  (*pfnUtf16Free)(BSTR pwszString);
-        void  (*pfnUtf8Free)(char *pszString);
-
-        int   (*pfnUtf16ToUtf8)(CBSTR pwszString, char **ppszString);
-        int   (*pfnUtf8ToUtf16)(const char *pszString, BSTR *ppwszString);
+        void (*pfnComInitialize)(IVirtualBox **virtualBox, ISession **session);
+        void (*pfnComUninitialize)(void);
+
+        void (*pfnComUnallocMem)(void *pv);
+        void (*pfnUtf16Free)(BSTR pwszString);
+        void (*pfnUtf8Free)(char *pszString);
+
+        int (*pfnUtf16ToUtf8)(CBSTR pwszString, char **ppszString);
+        int (*pfnUtf8ToUtf16)(const char *pszString, BSTR *ppwszString);
 
         /** Tail version, same as uVersion. */
Index: /trunk/src/VBox/Main/cbinding/VBoxCAPIGlue.c
===================================================================
--- /trunk/src/VBox/Main/cbinding/VBoxCAPIGlue.c	(revision 54026)
+++ /trunk/src/VBox/Main/cbinding/VBoxCAPIGlue.c	(revision 54027)
@@ -5,5 +5,5 @@
 
 /*
- * Copyright (C) 2008-2014 Oracle Corporation
+ * Copyright (C) 2008-2015 Oracle Corporation
  *
  * Permission is hereby granted, free of charge, to any person
@@ -164,14 +164,22 @@
 #ifndef WIN32
     g_hVBoxCAPI = dlopen(szName, RTLD_NOW | RTLD_LOCAL);
+#else /* WIN32 */
+    g_hVBoxCAPI = LoadLibraryExA(szName, NULL /* hFile */, 0 /* dwFlags */);
+#endif /* WIN32 */
     if (g_hVBoxCAPI)
     {
         PFNVBOXGETCAPIFUNCTIONS pfnGetFunctions;
+#ifndef WIN32
         pfnGetFunctions = (PFNVBOXGETCAPIFUNCTIONS)(uintptr_t)
             dlsym(g_hVBoxCAPI, VBOX_GET_CAPI_FUNCTIONS_SYMBOL_NAME);
-#ifdef VBOX_GET_XPCOM_FUNCTIONS_SYMBOL_NAME
+# ifdef VBOX_GET_XPCOM_FUNCTIONS_SYMBOL_NAME
         if (!pfnGetFunctions)
             pfnGetFunctions = (PFNVBOXGETCAPIFUNCTIONS)(uintptr_t)
                 dlsym(g_hVBoxCAPI, VBOX_GET_XPCOM_FUNCTIONS_SYMBOL_NAME);
-#endif /* VBOX_GET_XPCOM_FUNCTIONS_SYMBOL_NAME */
+# endif /* VBOX_GET_XPCOM_FUNCTIONS_SYMBOL_NAME */
+#else /* WIN32 */
+        pfnGetFunctions = (PFNVBOXGETCAPIFUNCTIONS)
+            GetProcAddress(g_hVBoxCAPI, VBOX_GET_CAPI_FUNCTIONS_SYMBOL_NAME);
+#endif /* WIN32 */
         if (pfnGetFunctions)
         {
@@ -179,49 +187,49 @@
             if (g_pVBoxFuncs)
             {
-                g_pfnGetFunctions = pfnGetFunctions;
-                return 0;
+                if (   (   VBOX_CAPI_MAJOR(g_pVBoxFuncs->uVersion)
+                        == VBOX_CAPI_MAJOR(VBOX_CAPI_VERSION))
+                    && (   VBOX_CAPI_MINOR(g_pVBoxFuncs->uVersion)
+                        >= VBOX_CAPI_MINOR(VBOX_CAPI_VERSION)))
+                {
+                    g_pfnGetFunctions = pfnGetFunctions;
+                    return 0;
+                }
+                setErrMsg(1, "%.80s: pfnGetFunctions(%#x) returned incompatible version %#x",
+                          szName, VBOX_CAPI_VERSION, g_pVBoxFuncs->uVersion);
+                g_pVBoxFuncs = NULL;
             }
-
-            /* bail out */
-            setErrMsg(1, "%.80s: pfnGetFunctions(%#x) failed",
-                      szName, VBOX_CAPI_VERSION);
+            else
+            {
+                /* bail out */
+                setErrMsg(1, "%.80s: pfnGetFunctions(%#x) failed",
+                          szName, VBOX_CAPI_VERSION);
+            }
         }
         else
+        {
+#ifndef WIN32
             setErrMsg(1, "dlsym(%.80s/%.32s): %.128s",
                       szName, VBOX_GET_CAPI_FUNCTIONS_SYMBOL_NAME, dlerror());
-        dlclose(g_hVBoxCAPI);
-        g_hVBoxCAPI = NULL;
-    }
-    else
-        setErrMsg(0, "dlopen(%.80s): %.160s", szName, dlerror());
-#else /* !WIN32 */
-    g_hVBoxCAPI = LoadLibraryExA(szName, NULL /* hFile */, 0 /* dwFlags */);
-    if (g_hVBoxCAPI)
-    {
-        PFNVBOXGETCAPIFUNCTIONS pfnGetFunctions;
-        pfnGetFunctions = (PFNVBOXGETCAPIFUNCTIONS)
-            GetProcAddress(g_hVBoxCAPI, VBOX_GET_CAPI_FUNCTIONS_SYMBOL_NAME);
-        if (pfnGetFunctions)
-        {
-            g_pVBoxFuncs = pfnGetFunctions(VBOX_CAPI_VERSION);
-            if (g_pVBoxFuncs)
-            {
-                g_pfnGetFunctions = pfnGetFunctions;
-                return 0;
-            }
-
-            /* bail out */
-            setErrMsg(1, "%.80s: pfnGetFunctions(%#x) failed",
-                      szName, VBOX_CAPI_VERSION);
-        }
-        else
+#else /* WIN32 */
             setErrMsg(1, "GetProcAddress(%.80s/%.32s): %d",
                       szName, VBOX_GET_CAPI_FUNCTIONS_SYMBOL_NAME, GetLastError());
+#endif /* WIN32 */
+        }
+
+#ifndef WIN32
+        dlclose(g_hVBoxCAPI);
+#else /* WIN32 */
         FreeLibrary(g_hVBoxCAPI);
+#endif /* WIN32 */
         g_hVBoxCAPI = NULL;
     }
     else
+    {
+#ifndef WIN32
+        setErrMsg(0, "dlopen(%.80s): %.160s", szName, dlerror());
+#else /* WIN32 */
         setErrMsg(0, "LoadLibraryEx(%.80s): %d", szName, GetLastError());
-#endif /* !WIN32 */
+#endif /* WIN32 */
+    }
 
     return -1;
Index: /trunk/src/VBox/Main/cbinding/capiidl.xsl
===================================================================
--- /trunk/src/VBox/Main/cbinding/capiidl.xsl	(revision 54026)
+++ /trunk/src/VBox/Main/cbinding/capiidl.xsl	(revision 54027)
@@ -1483,5 +1483,27 @@
     int (*pfnInterruptEventQueueProcessing)(void);
 
-    /** Tail version, same as uVersion. */
+    /**
+     * Clear memory used by a UTF-8 string. Must be zero terminated.
+     * Can be used for any UTF-8 or ASCII/ANSI string.
+     *
+     * @param pszString     input/output string
+     */
+    void (*pfnUtf8Clear)(char *pszString);
+    /**
+     * Clear memory used by a UTF-16 string. Must be zero terminated.
+     * Can be used for any UTF-16 or UCS-2 string.
+     *
+     * @param pwszString    input/output string
+     */
+     void (*pfnUtf16Clear)(BSTR pwszString);
+
+    /** Tail version, same as uVersion.
+     *
+     * This should only be accessed if for some reason an API client needs
+     * exactly the version it requested, or if cb is used to calculate the
+     * address of this field. It may move as the structure before this is
+     * allowed to grow as long as all the data from earlier minor versions
+     * remains at the same place.
+     */
     unsigned uEndVersion;
 } VBOXCAPI;
@@ -1500,7 +1522,15 @@
 #endif /* !WIN32 */
 
+/** Extract the C API style major version.
+ * Useful for comparing the interface version in VBOXCAPI::uVersion. */
+#define VBOX_CAPI_MAJOR(x) (((x) &amp; 0xffff0000U) &gt;&gt; 16)
+
+/** Extract the C API style major version.
+ * Useful for comparing the interface version in VBOXCAPI::uVersion. */
+#define VBOX_CAPI_MINOR(x) ((x) &amp; 0x0000ffffU)
+
 /** The current interface version.
  * For use with VBoxGetCAPIFunctions and to be found in VBOXCAPI::uVersion. */
-#define VBOX_CAPI_VERSION 0x00040000U
+#define VBOX_CAPI_VERSION 0x00040001U
 
 #ifndef WIN32
