[vlc-devel] [PATCH] Don't use old ActiveX control

Poe pcastets at actech-innovation.com
Tue Jun 10 14:13:24 CEST 2008


Remove all references to VLCControl
Use VLCControl2 instead
---
 projects/activex/main.cpp         |   25 +---
 projects/activex/objectsafety.cpp |    4 +-
 projects/activex/plugin.cpp       |    9 +-
 projects/activex/plugin.h         |    4 -
 projects/activex/vlccontrol2.cpp  |  325 ++++++++++++++++++++++++++++++++++++-
 projects/activex/vlccontrol2.h    |    5 +
 6 files changed, 333 insertions(+), 39 deletions(-)

diff --git a/projects/activex/main.cpp b/projects/activex/main.cpp
index f3e3f5f..cd1eaa8 100644
--- a/projects/activex/main.cpp
+++ b/projects/activex/main.cpp
@@ -66,8 +66,7 @@ STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
 
     *ppv = NULL;
 
-    if( (CLSID_VLCPlugin == rclsid )
-     || ( CLSID_VLCPlugin2 == rclsid) )
+    if( CLSID_VLCPlugin2 == rclsid )
     {
         VLCPluginClass *plugin = new VLCPluginClass(&i_class_ref, h_instance, rclsid);
         hr = plugin->QueryInterface(riid, ppv);
@@ -157,8 +156,6 @@ STDAPI DllUnregisterServer(VOID)
             _CATID_SafeForScripting,
         };
 
-        pcr->UnRegisterClassImplCategories(CLSID_VLCPlugin,
-                sizeof(implCategories)/sizeof(CATID), implCategories);
         pcr->UnRegisterClassImplCategories(CLSID_VLCPlugin2,
                 sizeof(implCategories)/sizeof(CATID), implCategories);
         pcr->Release();
@@ -166,7 +163,6 @@ STDAPI DllUnregisterServer(VOID)
 
     SHDeleteKey(HKEY_CLASSES_ROOT, TEXT(PROGID_STR));
 
-    UnregisterProgID(CLSID_VLCPlugin, 2);
     UnregisterProgID(CLSID_VLCPlugin2, 1);
 
     return S_OK;
@@ -307,8 +303,7 @@ STDAPI DllRegisterServer(VOID)
     if( ERROR_SUCCESS != RegOpenKeyEx(HKEY_CLASSES_ROOT, TEXT("CLSID"), 0, KEY_CREATE_SUB_KEY, &hBaseKey) )
         return SELFREG_E_CLASS;
 
-    RegisterClassID(hBaseKey, CLSID_VLCPlugin, 1, FALSE, DllPath, DllPathLen);
-    RegisterClassID(hBaseKey, CLSID_VLCPlugin2, 2, TRUE, DllPath, DllPathLen);
+    RegisterClassID(hBaseKey, CLSID_VLCPlugin2, 1, TRUE, DllPath, DllPathLen);
 
     RegCloseKey(hBaseKey);
 
@@ -324,8 +319,6 @@ STDAPI DllRegisterServer(VOID)
             _CATID_SafeForScripting,
         };
 
-        pcr->RegisterClassImplCategories(CLSID_VLCPlugin,
-                sizeof(implCategories)/sizeof(CATID), implCategories);
         pcr->RegisterClassImplCategories(CLSID_VLCPlugin2,
                 sizeof(implCategories)/sizeof(CATID), implCategories);
         pcr->Release();
@@ -373,24 +366,19 @@ STDAPI_(int) WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw)
 
     IUnknown *classProc = NULL;
 
-    if( FAILED(DllGetClassObject(CLSID_VLCPlugin, IID_IUnknown, (LPVOID *)&classProc)) )
+    if( FAILED(DllGetClassObject(CLSID_VLCPlugin2, IID_IUnknown, (LPVOID *)&classProc)) )
         return 0;
  
     DWORD dwRegisterClassObject;
-    DWORD dwRegisterClassObject2;
 
-    if( FAILED(CoRegisterClassObject(CLSID_VLCPlugin, classProc,
+    if( FAILED(CoRegisterClassObject(CLSID_VLCPlugin2, classProc,
         CLSCTX_LOCAL_SERVER, REGCLS_MULTIPLEUSE, &dwRegisterClassObject)) )
         return 0;
 
     DWORD dwRegisterActiveObject;
 
-    if( FAILED(RegisterActiveObject(classProc, CLSID_VLCPlugin,
-                    ACTIVEOBJECT_WEAK, &dwRegisterActiveObject)) )
-        return 0;
-
     if( FAILED(RegisterActiveObject(classProc, CLSID_VLCPlugin2,
-                    ACTIVEOBJECT_WEAK, &dwRegisterActiveObject2)) )
+                    ACTIVEOBJECT_WEAK, &dwRegisterActiveObject)) )
         return 0;
 
     classProc->Release();
@@ -421,9 +409,6 @@ STDAPI_(int) WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw)
     if( SUCCEEDED(RevokeActiveObject(dwRegisterActiveObject, NULL)) )
         CoRevokeClassObject(dwRegisterClassObject);
 
-    if( SUCCEEDED(RevokeActiveObject(dwRegisterActiveObject2, NULL)) )
-        CoRevokeClassObject(dwRegisterClassObject2);
-
     // Reached on WM_QUIT message
     OleUninitialize();
     return ((int) msg.wParam);
diff --git a/projects/activex/objectsafety.cpp b/projects/activex/objectsafety.cpp
index 3806d36..8b2e097 100644
--- a/projects/activex/objectsafety.cpp
+++ b/projects/activex/objectsafety.cpp
@@ -44,7 +44,7 @@ STDMETHODIMP VLCObjectSafety::GetInterfaceSafetyOptions(
     *pdwSupportedOptions = INTERFACESAFE_FOR_UNTRUSTED_DATA|INTERFACESAFE_FOR_UNTRUSTED_CALLER;
 
     if( (IID_IDispatch == riid)
-     || (IID_IVLCControl == riid) )
+     || (IID_IVLCControl2 == riid) )
     {
         *pdwEnabledOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER;
         return NOERROR;
@@ -68,7 +68,7 @@ STDMETHODIMP VLCObjectSafety::SetInterfaceSafetyOptions(
 )
 {
     if( (IID_IDispatch == riid)
-     || (IID_IVLCControl == riid) )
+     || (IID_IVLCControl2 == riid) )
     {
         if( (INTERFACESAFE_FOR_UNTRUSTED_CALLER == dwOptionSetMask)
          && (INTERFACESAFE_FOR_UNTRUSTED_CALLER == dwEnabledOptions) )
diff --git a/projects/activex/plugin.cpp b/projects/activex/plugin.cpp
index 5aa6400..0e7f535 100644
--- a/projects/activex/plugin.cpp
+++ b/projects/activex/plugin.cpp
@@ -32,7 +32,6 @@
 #include "provideclassinfo.h"
 #include "connectioncontainer.h"
 #include "objectsafety.h"
-#include "vlccontrol.h"
 #include "vlccontrol2.h"
 #include "viewobject.h"
 #include "dataobject.h"
@@ -219,7 +218,6 @@ VLCPlugin::VLCPlugin(VLCPluginClass *p_class, LPUNKNOWN pUnkOuter) :
     vlcProvideClassInfo = new VLCProvideClassInfo(this);
     vlcConnectionPointContainer = new VLCConnectionPointContainer(this);
     vlcObjectSafety = new VLCObjectSafety(this);
-    vlcControl = new VLCControl(this);
     vlcControl2 = new VLCControl2(this);
     vlcViewObject = new VLCViewObject(this);
     vlcDataObject = new VLCDataObject(this);
@@ -249,7 +247,6 @@ VLCPlugin::~VLCPlugin()
     delete vlcDataObject;
     delete vlcViewObject;
     delete vlcControl2;
-    delete vlcControl;
     delete vlcConnectionPointContainer;
     delete vlcProvideClassInfo;
     delete vlcPersistPropertyBag;
@@ -303,11 +300,7 @@ STDMETHODIMP VLCPlugin::QueryInterface(REFIID riid, void **ppv)
     else if( IID_IObjectSafety == riid )
         *ppv = reinterpret_cast<LPVOID>(vlcObjectSafety);
     else if( IID_IDispatch == riid )
-        *ppv = (CLSID_VLCPlugin2 == getClassID()) ?
-                reinterpret_cast<LPVOID>(vlcControl2) :
-                reinterpret_cast<LPVOID>(vlcControl);
-    else if( IID_IVLCControl == riid )
-        *ppv = reinterpret_cast<LPVOID>(vlcControl);
+        *ppv = reinterpret_cast<LPVOID>(vlcControl2);
     else if( IID_IVLCControl2 == riid )
         *ppv = reinterpret_cast<LPVOID>(vlcControl2);
     else if( IID_IViewObject == riid )
diff --git a/projects/activex/plugin.h b/projects/activex/plugin.h
index d21f8a6..001b176 100644
--- a/projects/activex/plugin.h
+++ b/projects/activex/plugin.h
@@ -27,11 +27,8 @@
 #include <olectl.h>
 
 #include <vlc/vlc.h>
-
-
 #include <vlc/libvlc.h>
 
-extern "C" const GUID CLSID_VLCPlugin;
 extern "C" const GUID CLSID_VLCPlugin2;
 extern "C" const GUID LIBID_AXVLC;
 extern "C" const GUID DIID_DVLCEvents;
@@ -248,7 +245,6 @@ private:
     class VLCProvideClassInfo *vlcProvideClassInfo;
     class VLCConnectionPointContainer *vlcConnectionPointContainer;
     class VLCObjectSafety *vlcObjectSafety;
-    class VLCControl *vlcControl;
     class VLCControl2 *vlcControl2;
     class VLCViewObject *vlcViewObject;
     class VLCDataObject *vlcDataObject;
diff --git a/projects/activex/vlccontrol2.cpp b/projects/activex/vlccontrol2.cpp
index 26548c0..49d2590 100644
--- a/projects/activex/vlccontrol2.cpp
+++ b/projects/activex/vlccontrol2.cpp
@@ -23,7 +23,6 @@
 
 #include "plugin.h"
 #include "vlccontrol2.h"
-#include "vlccontrol.h"
 
 #include "utils.h"
 
@@ -525,7 +524,7 @@ STDMETHODIMP VLCInput::put_time(double time)
         libvlc_media_player_t *p_md = libvlc_playlist_get_media_player(p_libvlc, &ex);
         if( ! libvlc_exception_raised(&ex) )
         {
-            libvlc_media_player_set_time(p_md, (vlc_int64_t)time, &ex);
+            libvlc_media_player_set_time(p_md, (int64_t)time, &ex);
             libvlc_media_player_release(p_md);
             if( ! libvlc_exception_raised(&ex) )
             {
@@ -1723,7 +1722,7 @@ STDMETHODIMP VLCPlaylist::add(BSTR uri, VARIANT name, VARIANT options, long* ite
         int i_options;
         char **ppsz_options;
 
-        hr = VLCControl::CreateTargetOptions(CP_UTF8, &options, &ppsz_options, &i_options);
+        hr = VLCControl2::CreateTargetOptions(CP_UTF8, &options, &ppsz_options, &i_options);
         if( FAILED(hr) )
         {
             CoTaskMemFree(psz_uri);
@@ -1748,7 +1747,7 @@ STDMETHODIMP VLCPlaylist::add(BSTR uri, VARIANT name, VARIANT options, long* ite
                     const_cast<const char **>(ppsz_options),
                     &ex);
 
-        VLCControl::FreeTargetOptions(ppsz_options, i_options);
+        VLCControl2::FreeTargetOptions(ppsz_options, i_options);
         CoTaskMemFree(psz_uri);
         if( psz_name )
             CoTaskMemFree(psz_name);
@@ -2782,7 +2781,7 @@ STDMETHODIMP VLCControl2::get_VersionInfo(BSTR *version)
     if( NULL == version )
         return E_POINTER;
 
-    const char *versionStr = VLC_Version();
+    const char *versionStr = libvlc_get_version();
     if( NULL != versionStr )
     {
         *version = BSTRFromCStr(CP_UTF8, versionStr);
@@ -2909,3 +2908,319 @@ STDMETHODIMP VLCControl2::get_video(IVLCVideo** obj)
     }
     return E_OUTOFMEMORY;
 };
+
+
+HRESULT VLCControl2::CreateTargetOptions(int codePage, VARIANT *options, char ***cOptions, int *cOptionCount)
+{
+    HRESULT hr = E_INVALIDARG;
+    if( VT_ERROR == V_VT(options) )
+    {
+        if( DISP_E_PARAMNOTFOUND == V_ERROR(options) )
+        {
+            // optional parameter not set
+            *cOptions = NULL;
+            *cOptionCount = 0;
+            return NOERROR;
+        }
+    }
+    else if( (VT_EMPTY == V_VT(options)) || (VT_NULL == V_VT(options)) )
+    {
+        // null parameter
+        *cOptions = NULL;
+        *cOptionCount = 0;
+        return NOERROR;
+    }
+    else if( VT_DISPATCH == V_VT(options) )
+    {
+        // if object is a collection, retrieve enumerator
+        VARIANT colEnum;
+        V_VT(&colEnum) = VT_UNKNOWN;
+        hr = GetObjectProperty(V_DISPATCH(options), DISPID_NEWENUM, colEnum);
+        if( SUCCEEDED(hr) )
+        {
+            IEnumVARIANT *enumVar;
+            hr = V_UNKNOWN(&colEnum)->QueryInterface(IID_IEnumVARIANT, (LPVOID *)&enumVar);
+            if( SUCCEEDED(hr) )
+            {
+                long pos = 0;
+                long capacity = 16;
+                VARIANT option;
+
+                *cOptions = (char **)CoTaskMemAlloc(capacity*sizeof(char *));
+                if( NULL != *cOptions )
+                {
+                    ZeroMemory(*cOptions, sizeof(char *)*capacity);
+                    while( SUCCEEDED(hr) && (S_OK == enumVar->Next(1, &option, NULL)) )
+                    {
+                        if( VT_BSTR == V_VT(&option) )
+                        {
+                            char *cOption = CStrFromBSTR(codePage, V_BSTR(&option));
+                            (*cOptions)[pos] = cOption;
+                            if( NULL != cOption )
+                            {
+                                ++pos;
+                                if( pos == capacity )
+                                {
+                                    char **moreOptions = (char **)CoTaskMemRealloc(*cOptions, (capacity+16)*sizeof(char *));
+                                    if( NULL != moreOptions )
+                                    {
+                                        ZeroMemory(moreOptions+capacity, sizeof(char *)*16);
+                                        capacity += 16;
+                                        *cOptions = moreOptions;
+                                    }
+                                    else
+                                        hr = E_OUTOFMEMORY;
+                                }
+                            }
+                            else
+                                hr = ( SysStringLen(V_BSTR(&option)) > 0 ) ?
+                                    E_OUTOFMEMORY : E_INVALIDARG;
+                        }
+                        else
+                            hr = E_INVALIDARG;
+
+                        VariantClear(&option);
+                    }
+                    *cOptionCount = pos;
+                    if( FAILED(hr) )
+                    {
+                        // free already processed elements
+                        FreeTargetOptions(*cOptions, *cOptionCount);
+                    }
+                }
+                else
+                    hr = E_OUTOFMEMORY;
+
+                enumVar->Release();
+            }
+        }
+        else
+        {
+            // coerce object into a string and parse it
+            VARIANT v_name;
+            VariantInit(&v_name);
+            hr = VariantChangeType(&v_name, options, 0, VT_BSTR);
+            if( SUCCEEDED(hr) )
+            {
+                hr = parseStringOptions(codePage, V_BSTR(&v_name), cOptions, cOptionCount);
+                VariantClear(&v_name);
+            }
+        }
+    }
+    else if( V_ISARRAY(options) )
+    {
+        // array parameter
+        SAFEARRAY *array = V_ISBYREF(options) ? *V_ARRAYREF(options) : V_ARRAY(options);
+
+        if( SafeArrayGetDim(array) != 1 )
+            return E_INVALIDARG;
+
+        long lBound = 0;
+        long uBound = 0;
+        SafeArrayGetLBound(array, 1, &lBound);
+        SafeArrayGetUBound(array, 1, &uBound);
+
+        // have we got any options
+        if( uBound >= lBound )
+        {
+            VARTYPE vType;
+            hr = SafeArrayGetVartype(array, &vType);
+            if( FAILED(hr) )
+                return hr;
+
+            long pos;
+
+            // marshall options into an array of C strings
+            if( VT_VARIANT == vType )
+            {
+                *cOptions = (char **)CoTaskMemAlloc(sizeof(char *)*(uBound-lBound+1));
+                if( NULL == *cOptions )
+                    return E_OUTOFMEMORY;
+
+                ZeroMemory(*cOptions, sizeof(char *)*(uBound-lBound+1));
+                for(pos=lBound; (pos<=uBound) && SUCCEEDED(hr); ++pos )
+                {
+                    VARIANT option;
+                    hr = SafeArrayGetElement(array, &pos, &option);
+                    if( SUCCEEDED(hr) )
+                    {
+                        if( VT_BSTR == V_VT(&option) )
+                        {
+                            char *cOption = CStrFromBSTR(codePage, V_BSTR(&option));
+                            (*cOptions)[pos-lBound] = cOption;
+                            if( NULL == cOption )
+                                hr = ( SysStringLen(V_BSTR(&option)) > 0 ) ?
+                                    E_OUTOFMEMORY : E_INVALIDARG;
+                        }
+                        else
+                            hr = E_INVALIDARG;
+                        VariantClear(&option);
+                    }
+                }
+            }
+            else if( VT_BSTR == vType )
+            {
+                *cOptions = (char **)CoTaskMemAlloc(sizeof(char *)*(uBound-lBound+1));
+                if( NULL == *cOptions )
+                    return E_OUTOFMEMORY;
+
+                ZeroMemory(*cOptions, sizeof(char *)*(uBound-lBound+1));
+                for(pos=lBound; (pos<=uBound) && SUCCEEDED(hr); ++pos )
+                {
+                    BSTR option;
+                    hr = SafeArrayGetElement(array, &pos, &option);
+                    if( SUCCEEDED(hr) )
+                    {
+                        char *cOption = CStrFromBSTR(codePage, option);
+
+                        (*cOptions)[pos-lBound] = cOption;
+                        if( NULL == cOption )
+                            hr = ( SysStringLen(option) > 0 ) ?
+                                E_OUTOFMEMORY : E_INVALIDARG;
+                        SysFreeString(option);
+                    }
+                }
+            }
+            else
+            {
+                // unsupported type
+                return E_INVALIDARG;
+            }
+
+            *cOptionCount = pos-lBound;
+            if( FAILED(hr) )
+            {
+                // free already processed elements
+                FreeTargetOptions(*cOptions, *cOptionCount);
+            }
+        }
+        else
+        {
+            // empty array
+            *cOptions = NULL;
+            *cOptionCount = 0;
+            return NOERROR;
+        }
+    }
+    else if( VT_UNKNOWN == V_VT(options) )
+    {
+        // coerce object into a string and parse it
+        VARIANT v_name;
+        VariantInit(&v_name);
+        hr = VariantChangeType(&v_name, options, 0, VT_BSTR);
+        if( SUCCEEDED(hr) )
+        {
+            hr = parseStringOptions(codePage, V_BSTR(&v_name), cOptions, cOptionCount);
+            VariantClear(&v_name);
+        }
+    }
+    else if( VT_BSTR == V_VT(options) )
+    {
+        hr = parseStringOptions(codePage, V_BSTR(options), cOptions, cOptionCount);
+    }
+    return hr;
+};
+
+void VLCControl2::FreeTargetOptions(char **cOptions, int cOptionCount)
+{
+    // clean up
+    if( NULL != cOptions )
+    {
+        for( int pos=0; pos<cOptionCount; ++pos )
+        {
+            char *cOption = cOptions[pos];
+            if( NULL != cOption )
+                CoTaskMemFree(cOption);
+            else
+                break;
+        }
+        CoTaskMemFree(cOptions);
+    }
+};
+
+static HRESULT parseStringOptions(int codePage, BSTR bstr, char*** cOptions, int *cOptionCount)
+{
+    HRESULT hr = E_INVALIDARG;
+    if( SysStringLen(bstr) > 0 )
+    {
+        hr = E_OUTOFMEMORY;
+        char *s = CStrFromBSTR(codePage, bstr);
+        char *val = s;
+        if( val )
+        {
+            long capacity = 16;
+            char **options = (char **)CoTaskMemAlloc(capacity*sizeof(char *));
+            if( options )
+            {
+                int nOptions = 0;
+
+                char *end = val + strlen(val);
+                while( val < end )
+                {
+                    // skip leading blanks
+                    while( (val < end)
+                        && ((*val == ' ' ) || (*val == '\t')) )
+                        ++val;
+
+                    char *start = val;
+                    // skip till we get a blank character
+                    while( (val < end)
+                        && (*val != ' ' )
+                        && (*val != '\t') )
+                    {
+                        char c = *(val++);
+                        if( ('\'' == c) || ('"' == c) )
+                        {
+                            // skip till end of string
+                            while( (val < end) && (*(val++) != c ) );
+                        }
+                    }
+
+                    if( val > start )
+                    {
+                        if( nOptions == capacity )
+                        {
+                            capacity += 16;
+                            char **moreOptions = (char **)CoTaskMemRealloc(options, capacity*sizeof(char*));
+                            if( ! moreOptions )
+                            {
+                                /* failed to allocate more memory */
+                                CoTaskMemFree(s);
+                                /* return what we got so far */
+                                *cOptionCount = nOptions;
+                                *cOptions = options;
+                                return NOERROR;
+                            }
+                            options = moreOptions;
+                        }
+                        *(val++) = '\0';
+                        options[nOptions] = (char *)CoTaskMemAlloc(val-start);
+                        if( options[nOptions] )
+                        {
+                            memcpy(options[nOptions], start, val-start);
+                            ++nOptions;
+                        }
+                        else
+                        {
+                            /* failed to allocate memory */
+                            CoTaskMemFree(s);
+                            /* return what we got so far */
+                            *cOptionCount = nOptions;
+                            *cOptions = options;
+                            return NOERROR;
+                        }
+                    }
+                    else
+                        // must be end of string
+                        break;
+                }
+                *cOptionCount = nOptions;
+                *cOptions = options;
+                hr = NOERROR;
+            }
+            CoTaskMemFree(s);
+        }
+    }
+    return hr;
+}
+
diff --git a/projects/activex/vlccontrol2.h b/projects/activex/vlccontrol2.h
index 7596676..7e3a22b 100644
--- a/projects/activex/vlccontrol2.h
+++ b/projects/activex/vlccontrol2.h
@@ -600,6 +600,9 @@ public:
     STDMETHODIMP get_playlist(IVLCPlaylist**);
     STDMETHODIMP get_video(IVLCVideo**);
 
+    static HRESULT CreateTargetOptions(int codePage, VARIANT *options, char ***cOptions, int *cOptionCount);
+    static void FreeTargetOptions(char **cOptions, int cOptionCount);
+
 protected:
     HRESULT loadTypeInfo();
 
@@ -614,4 +617,6 @@ private:
     VLCVideo*       _p_vlcvideo;
 };
 
+static HRESULT parseStringOptions(int codePage, BSTR bstr, char*** cOptions, int *cOptionCount);
+
 #endif
-- 
1.5.4.3




More information about the vlc-devel mailing list