From bf33f9410ff4e1edea9fa0054d2bf68b84f026f8 Mon Sep 17 00:00:00 2001 From: Rob Shearman Date: Thu, 28 Dec 2006 02:42:01 +0000 Subject: [PATCH] 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 file changed, 46 insertions(+), 11 deletions(-) diff --git a/dlls/ole32/moniker.c b/dlls/ole32/moniker.c index 97f8914db68..22fee9f050a 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_data(IMoniker *pMoniker, MInterfacePointer { 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; }