Rob Shearman : ole32: Contrary to MSDN, IROTData doesn' t need to be implemented for a moniker to be usable with the running object table .

Alexandre Julliard julliard at wine.codeweavers.com
Thu Dec 28 07:40:34 CST 2006


Module: wine
Branch: master
Commit: bf33f9410ff4e1edea9fa0054d2bf68b84f026f8
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=bf33f9410ff4e1edea9fa0054d2bf68b84f026f8

Author: Rob Shearman <rob at codeweavers.com>
Date:   Thu Dec 28 02:42:01 2006 +0000

ole32: Contrary to MSDN, IROTData doesn't need to be implemented for a moniker to be usable with the running object table.

If IROTData isn't available, fall back to a path that uses the display 
name and the clsid of the moniker to generate the comparison data.

---

 dlls/ole32/moniker.c |   57 ++++++++++++++++++++++++++++++++++++++++---------
 1 files changed, 46 insertions(+), 11 deletions(-)

diff --git a/dlls/ole32/moniker.c b/dlls/ole32/moniker.c
index 97f8914..22fee9f 100644
--- a/dlls/ole32/moniker.c
+++ b/dlls/ole32/moniker.c
@@ -40,6 +40,7 @@
 
 #include "wine/list.h"
 #include "wine/debug.h"
+#include "wine/unicode.h"
 
 #include "compobj_private.h"
 
@@ -143,22 +144,56 @@ static HRESULT get_moniker_comparison_da
 {
     HRESULT hr;
     IROTData *pROTData = NULL;
-    ULONG size = MAX_COMPARISON_DATA;
     hr = IMoniker_QueryInterface(pMoniker, &IID_IROTData, (void *)&pROTData);
-    if (hr != S_OK)
+    if (SUCCEEDED(hr))
     {
-        ERR("Failed to query moniker for IROTData interface, hr = 0x%08x\n", hr);
-        return hr;
+        ULONG size = MAX_COMPARISON_DATA;
+        *moniker_data = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(MInterfacePointer, abData[size]));
+        hr = IROTData_GetComparisonData(pROTData, (*moniker_data)->abData, size, &size);
+        if (hr != S_OK)
+        {
+            ERR("Failed to copy comparison data into buffer, hr = 0x%08x\n", hr);
+            HeapFree(GetProcessHeap(), 0, *moniker_data);
+            return hr;
+        }
+        (*moniker_data)->ulCntData = size;
     }
-    *moniker_data = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(MInterfacePointer, abData[size]));
-    hr = IROTData_GetComparisonData(pROTData, (*moniker_data)->abData, size, &size);
-    if (hr != S_OK)
+    else
     {
-        ERR("Failed to copy comparison data into buffer, hr = 0x%08x\n", hr);
-        HeapFree(GetProcessHeap(), 0, *moniker_data);
-        return hr;
+        IBindCtx *pbc;
+        LPOLESTR pszDisplayName;
+        CLSID clsid;
+        int len;
+
+        TRACE("generating comparison data from display name\n");
+
+        hr = CreateBindCtx(0, &pbc);
+        if (FAILED(hr))
+            return hr;
+        hr = IMoniker_GetDisplayName(pMoniker, pbc, NULL, &pszDisplayName);
+        IBindCtx_Release(pbc);
+        if (FAILED(hr))
+            return hr;
+        hr = IMoniker_GetClassID(pMoniker, &clsid);
+        if (FAILED(hr))
+        {
+            CoTaskMemFree(pszDisplayName);
+            return hr;
+        }
+
+        len = strlenW(pszDisplayName);
+        *moniker_data = HeapAlloc(GetProcessHeap(), 0,
+            FIELD_OFFSET(MInterfacePointer, abData[sizeof(CLSID) + (len+1)*sizeof(WCHAR)]));
+        if (!*moniker_data)
+        {
+            CoTaskMemFree(pszDisplayName);
+            return E_OUTOFMEMORY;
+        }
+        (*moniker_data)->ulCntData = sizeof(CLSID) + (len+1)*sizeof(WCHAR);
+
+        memcpy(&(*moniker_data)->abData[0], &clsid, sizeof(clsid));
+        memcpy(&(*moniker_data)->abData[sizeof(clsid)], pszDisplayName, (len+1)*sizeof(WCHAR));
     }
-    (*moniker_data)->ulCntData = size;
     return S_OK;
 }
 




More information about the wine-cvs mailing list