[vlc-devel] [PATCH] activex: win64 fixes

Rafaël Carré funman at videolan.org
Sun Nov 13 03:11:39 CET 2011


GlobalInterfaceTable seems to be abused for storing pointers instead of
32 bits "cookies".
On win32 it seems the cookies happen to be equal to the pointer stored
Change the connection map to store the 32 bits cookies
Extend template to fetch the pointer from the cookie in VLCEnumConnectionsDereference

activex plugin is now in the same state than win32:
using share/test.html doesn't display any video and the state correctly displays "error"
---
 activex/connectioncontainer.cpp |   69 ++++++++++++++++++++++++--------------
 activex/connectioncontainer.h   |    2 +-
 activex/dataobject.cpp          |    7 ++--
 activex/utils.h                 |   18 ++++++----
 4 files changed, 59 insertions(+), 37 deletions(-)

diff --git a/activex/connectioncontainer.cpp b/activex/connectioncontainer.cpp
index 7d3800c..a454202 100644
--- a/activex/connectioncontainer.cpp
+++ b/activex/connectioncontainer.cpp
@@ -31,27 +31,43 @@
 #include <rpc.h>
 #include <rpcndr.h>
 
+#include <_mingw.h>
+
 using namespace std;
 
 ////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef __MINGW64_VERSION_MAJOR
 DEFINE_GUID(IID_IGlobalInterfaceTable,     0x00000146, 0x0000, 0x0000, 0xc0,0x00, 0x00,0x00,0x00,0x00,0x00,0x46);
+const GUID  IID_IGlobalInterfaceTable = { 0x00000146, 0, 0, {0xc0, 0, 0, 0, 0, 0, 0, 0x46} };
+#endif
+
 DEFINE_GUID(CLSID_StdGlobalInterfaceTable, 0x00000323, 0x0000, 0x0000, 0xc0,0x00, 0x00,0x00,0x00,0x00,0x00,0x46);
 
-const GUID  IID_IGlobalInterfaceTable = { 0x00000146, 0, 0, {0xc0, 0, 0, 0, 0, 0, 0, 0x46} };
 const CLSID CLSID_StdGlobalInterfaceTable = { 0x00000323, 0, 0, {0xc0, 0, 0, 0, 0, 0, 0, 0x46} };
 ////////////////////////////////////////////////////////////////////////////////////////////////
 
 /* this function object is used to return the value from a map pair */
 struct VLCEnumConnectionsDereference
 {
-    CONNECTDATA operator()(const map<DWORD,LPUNKNOWN>::iterator& i)
+    CONNECTDATA operator()(const map<DWORD,DWORD>::iterator& i, REFIID iid)
     {
         CONNECTDATA cd;
+        LPUNKNOWN p;
+        IGlobalInterfaceTable *m_pGIT;
+
+        // Get the Global Interface Table per-process singleton:
+        CoCreateInstance(CLSID_StdGlobalInterfaceTable, 0,
+                CLSCTX_INPROC_SERVER,
+                IID_IGlobalInterfaceTable,
+                reinterpret_cast<void**>(&m_pGIT));
+        HRESULT hr = m_pGIT->GetInterfaceFromGlobal( i->second, iid, reinterpret_cast<void**>(&p));
+        assert( SUCCEEDED(hr) );
 
-        i->second->AddRef();
+        p->AddRef();
 
         cd.dwCookie = i->first;
-        cd.pUnk     = i->second;
+        cd.pUnk     = p;
         return cd;
     };
 };
@@ -59,16 +75,16 @@ struct VLCEnumConnectionsDereference
 class VLCEnumConnections : public VLCEnumIterator<IID_IEnumConnections,
     IEnumConnections,
     CONNECTDATA,
-    map<DWORD,LPUNKNOWN>::iterator,
+    map<DWORD,DWORD>::iterator,
     VLCEnumConnectionsDereference>
 {
 public:
-    VLCEnumConnections(map<DWORD,LPUNKNOWN> &m) :
+    VLCEnumConnections(map<DWORD,DWORD> &m, REFIID iid) :
         VLCEnumIterator<IID_IEnumConnections,
             IEnumConnections,
             CONNECTDATA,
-            map<DWORD,LPUNKNOWN>::iterator,
-            VLCEnumConnectionsDereference> (m.begin(), m.end())
+            map<DWORD,DWORD>::iterator,
+            VLCEnumConnectionsDereference> (m.begin(), m.end(), iid)
     {};
 };
 
@@ -77,8 +93,9 @@ public:
 /* this function object is used to retain the dereferenced iterator value */
 struct VLCEnumConnectionPointsDereference
 {
-    LPCONNECTIONPOINT operator()(const vector<LPCONNECTIONPOINT>::iterator& i)
+    LPCONNECTIONPOINT operator()(const vector<LPCONNECTIONPOINT>::iterator& i, REFIID iid)
     {
+        (void)iid;
         LPCONNECTIONPOINT cp = *i;
         cp->AddRef();
         return cp;
@@ -92,12 +109,12 @@ class VLCEnumConnectionPoints: public VLCEnumIterator<IID_IEnumConnectionPoints,
     VLCEnumConnectionPointsDereference>
 {
 public:
-    VLCEnumConnectionPoints(vector<LPCONNECTIONPOINT>& v) :
+    VLCEnumConnectionPoints(vector<LPCONNECTIONPOINT>& v, REFIID iid) :
         VLCEnumIterator<IID_IEnumConnectionPoints,
             IEnumConnectionPoints,
             LPCONNECTIONPOINT,
             vector<LPCONNECTIONPOINT>::iterator,
-            VLCEnumConnectionPointsDereference> (v.begin(), v.end())
+            VLCEnumConnectionPointsDereference> (v.begin(), v.end(), iid)
     {};
 };
 
@@ -265,12 +282,12 @@ VLCConnectionPoint::VLCConnectionPoint(IConnectionPointContainer *p_cpc, REFIID
 VLCConnectionPoint::~VLCConnectionPoint()
 {
     // Revoke interfaces from the GIT:
-    map<DWORD,LPUNKNOWN>::iterator end = _connections.end();
-    map<DWORD,LPUNKNOWN>::iterator iter = _connections.begin();
+    map<DWORD,DWORD>::iterator end = _connections.end();
+    map<DWORD,DWORD>::iterator iter = _connections.begin();
 
     while( iter != end )
     {
-        m_pGIT->RevokeInterfaceFromGlobal((DWORD)iter->second);
+        m_pGIT->RevokeInterfaceFromGlobal(iter->second);
         ++iter;
     }
     m_pGIT->Release();
@@ -311,7 +328,7 @@ STDMETHODIMP VLCConnectionPoint::Advise(IUnknown *pUnk, DWORD *pdwCookie)
         if( SUCCEEDED(hr) )
         {
             *pdwCookie = ++dwCookieCounter;
-            _connections[*pdwCookie] = (LPUNKNOWN) dwGITCookie;
+            _connections[*pdwCookie] = dwGITCookie;
         }
         pUnk->Release();
     }
@@ -320,10 +337,10 @@ STDMETHODIMP VLCConnectionPoint::Advise(IUnknown *pUnk, DWORD *pdwCookie)
 
 STDMETHODIMP VLCConnectionPoint::Unadvise(DWORD pdwCookie)
 {
-    map<DWORD,LPUNKNOWN>::iterator pcd = _connections.find((DWORD)pdwCookie);
+    map<DWORD,DWORD>::iterator pcd = _connections.find((DWORD)pdwCookie);
     if( pcd != _connections.end() )
     {
-        m_pGIT->RevokeInterfaceFromGlobal((DWORD)pcd->second);
+        m_pGIT->RevokeInterfaceFromGlobal(pcd->second);
         _connections.erase(pdwCookie);
         return S_OK;
     }
@@ -335,24 +352,23 @@ STDMETHODIMP VLCConnectionPoint::EnumConnections(IEnumConnections **ppEnum)
     if( NULL == ppEnum )
         return E_POINTER;
 
-    *ppEnum = dynamic_cast<LPENUMCONNECTIONS>(new VLCEnumConnections(_connections));
+    *ppEnum = dynamic_cast<LPENUMCONNECTIONS>(new VLCEnumConnections(_connections, _iid));
 
     return (NULL != *ppEnum ) ? S_OK : E_OUTOFMEMORY;
 };
 
 void VLCConnectionPoint::fireEvent(DISPID dispId, DISPPARAMS *pDispParams)
 {
-    map<DWORD,LPUNKNOWN>::iterator end = _connections.end();
-    map<DWORD,LPUNKNOWN>::iterator iter = _connections.begin();
+    map<DWORD,DWORD>::iterator end = _connections.end();
+    map<DWORD,DWORD>::iterator iter = _connections.begin();
 
     HRESULT hr = S_OK;
 
     while( iter != end )
     {
-        DWORD dwCookie = (DWORD)iter->second;
         LPUNKNOWN pUnk;
 
-        hr = m_pGIT->GetInterfaceFromGlobal( dwCookie, _iid,
+        hr = m_pGIT->GetInterfaceFromGlobal( iter->second, _iid,
                                              reinterpret_cast<void **>(&pUnk) );
         if( SUCCEEDED(hr) )
         {
@@ -372,15 +388,15 @@ void VLCConnectionPoint::fireEvent(DISPID dispId, DISPPARAMS *pDispParams)
 
 void VLCConnectionPoint::firePropChangedEvent(DISPID dispId)
 {
-    map<DWORD,LPUNKNOWN>::iterator end = _connections.end();
-    map<DWORD,LPUNKNOWN>::iterator iter = _connections.begin();
+    map<DWORD,DWORD>::iterator end = _connections.end();
+    map<DWORD,DWORD>::iterator iter = _connections.begin();
 
     while( iter != end )
     {
         LPUNKNOWN pUnk;
         HRESULT hr;
 
-        hr = m_pGIT->GetInterfaceFromGlobal( (DWORD)iter->second, IID_IUnknown,
+        hr = m_pGIT->GetInterfaceFromGlobal( iter->second, IID_IUnknown,
                                               reinterpret_cast<void **>(&pUnk) );
         if( SUCCEEDED(hr) )
         {
@@ -461,7 +477,8 @@ STDMETHODIMP VLCConnectionPointContainer::EnumConnectionPoints(LPENUMCONNECTIONP
     if( NULL == ppEnum )
         return E_POINTER;
 
-    *ppEnum = dynamic_cast<LPENUMCONNECTIONPOINTS>(new VLCEnumConnectionPoints(_v_cps));
+    const IID iid = {0x0,0x0,0x0,{0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}};
+    *ppEnum = dynamic_cast<LPENUMCONNECTIONPOINTS>(new VLCEnumConnectionPoints(_v_cps, iid));
 
     return (NULL != *ppEnum ) ? S_OK : E_OUTOFMEMORY;
 };
diff --git a/activex/connectioncontainer.h b/activex/connectioncontainer.h
index 4f22504..f2d8052 100644
--- a/activex/connectioncontainer.h
+++ b/activex/connectioncontainer.h
@@ -73,7 +73,7 @@ private:
     REFIID _iid;
     IGlobalInterfaceTable *m_pGIT;
     IConnectionPointContainer *_p_cpc;
-    std::map<DWORD, LPUNKNOWN> _connections;
+    std::map<DWORD, DWORD> _connections;
 };
 
 //////////////////////////////////////////////////////////////////////////
diff --git a/activex/dataobject.cpp b/activex/dataobject.cpp
index e784096..f91b784 100644
--- a/activex/dataobject.cpp
+++ b/activex/dataobject.cpp
@@ -52,11 +52,11 @@ class VLCEnumFORMATETC : public VLCEnumIterator<IID_IEnumFORMATETC,
     vector<FORMATETC>::iterator>
 {
 public:
-    VLCEnumFORMATETC(vector<FORMATETC> v) :
+    VLCEnumFORMATETC(vector<FORMATETC> v, REFIID iid) :
         VLCEnumIterator<IID_IEnumFORMATETC,
         IEnumFORMATETC,
         FORMATETC,
-        vector<FORMATETC>::iterator>(v.begin(), v.end())
+        vector<FORMATETC>::iterator>(v.begin(), v.end(), iid)
     {};
 };
 
@@ -99,7 +99,8 @@ STDMETHODIMP VLCDataObject::EnumFormatEtc(DWORD dwDirection,
     if( NULL == ppEnum )
         return E_POINTER;
 
-    *ppEnum = new VLCEnumFORMATETC(_v_formatEtc);
+     const IID iid = {0x0,0x0,0x0,{0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}};
+    *ppEnum = new VLCEnumFORMATETC(_v_formatEtc, iid);
 
     return (NULL != *ppEnum ) ? S_OK : E_OUTOFMEMORY;
 };
diff --git a/activex/utils.h b/activex/utils.h
index 6234ab3..838a576 100644
--- a/activex/utils.h
+++ b/activex/utils.h
@@ -49,8 +49,9 @@ extern LPWSTR CombineURL(LPCWSTR baseUrl, LPCWSTR url);
 template <typename T, class Iterator>
 struct VLCDereference
 {
-    T operator()(const Iterator& i) const
+    T operator()(const Iterator& i, REFIID iid) const
     {
+        (void)iid;
         return *i;
     };
 };
@@ -61,19 +62,21 @@ class VLCEnumIterator : public Enumerator
 
 public:
 
-    VLCEnumIterator(const Iterator& from, const Iterator& to) :
+    VLCEnumIterator(const Iterator& from, const Iterator& to, REFIID iid) :
         _refcount(1),
         _begin(from),
         _curr(from),
-        _end(to)
+        _end(to),
+        _iid(iid)
     {};
 
-    VLCEnumIterator(const VLCEnumIterator& e) :
+    VLCEnumIterator(const VLCEnumIterator& e, REFIID iid) :
         Enumerator(),
         _refcount(e._refcount),
         _begin(e._begin),
         _curr(e._curr),
-        _end(e._end)
+        _end(e._end),
+        _iid(iid)
     {};
 
     virtual ~VLCEnumIterator()
@@ -125,7 +128,7 @@ public:
 
         while( (c < celt) && (_curr != _end) )
         {
-            rgelt[c] = dereference(_curr);
+            rgelt[c] = dereference(_curr, _iid);
             ++_curr;
             ++c;
         }
@@ -158,7 +161,7 @@ public:
     {
         if( NULL == ppEnum )
             return E_POINTER;
-        *ppEnum = dynamic_cast<Enumerator *>(new VLCEnumIterator(*this));
+        *ppEnum = dynamic_cast<Enumerator *>(new VLCEnumIterator(*this, _iid));
         return (NULL != *ppEnum ) ? S_OK : E_OUTOFMEMORY;
     };
 
@@ -166,6 +169,7 @@ private:
 
     LONG     _refcount;
     Iterator _begin, _curr, _end;
+    REFIID _iid;
 
     Dereference dereference;
 
-- 
1.7.5.4



More information about the vlc-devel mailing list