[PATCH 1/3] shell32: Add IQueryInfo in ShellFolder2_GetUIObjectOf [try 2]

Detlef Riekenberg wine.dev at web.de
Sun May 20 10:47:41 CDT 2012


try 2 with the hints from nikolay

--
By by ... Detlef
---
 dlls/shell32/folders.c       |  117 ++++++++++++++++++++++++++++++++++++++++++
 dlls/shell32/shell32_main.h  |    1 +
 dlls/shell32/shfldr_unixfs.c |    7 ++-
 3 files changed, 123 insertions(+), 2 deletions(-)

diff --git a/dlls/shell32/folders.c b/dlls/shell32/folders.c
index 4848644..3f3a103 100644
--- a/dlls/shell32/folders.c
+++ b/dlls/shell32/folders.c
@@ -44,6 +44,21 @@
 WINE_DEFAULT_DEBUG_CHANNEL(shell);
 
 /***********************************************************************
+ * IQueryInfo implementation
+ */
+typedef struct
+{
+    IQueryInfo IQueryInfo_iface;
+    LONG ref;
+    LPITEMIDLIST pidl;
+} IQueryInfoImpl;
+
+static inline IQueryInfoImpl *impl_from_IQueryInfo(IQueryInfo *iface)
+{
+    return CONTAINING_RECORD(iface, IQueryInfoImpl, IQueryInfo_iface);
+}
+
+/***********************************************************************
 *   IExtractIconW implementation
 */
 typedef struct
@@ -561,3 +576,105 @@ IExtractIconA *IExtractIconA_Constructor(LPCITEMIDLIST pidl)
 
     return &ei->IExtractIconA_iface;
 }
+
+/***********************************************************************
+ * IQueryInfo implementation
+ */
+
+static HRESULT WINAPI QueryInfo_fnQueryInterface(IQueryInfo* iface, REFIID riid, LPVOID *ppv)
+{
+    IQueryInfoImpl *This = impl_from_IQueryInfo(iface);
+
+    TRACE("(%p, %s, %p)\n",This, debugstr_guid(riid), ppv);
+
+    if (IsEqualGUID(&IID_IUnknown, riid) ||
+        IsEqualGUID(&IID_IQueryInfo, riid)) {
+        *ppv = &This->IQueryInfo_iface;
+        IQueryInfo_AddRef(iface);
+        return S_OK;
+    }
+
+    *ppv = NULL;
+    FIXME("(%p)->(%s %p) interface not supported\n", This, debugstr_guid(riid), ppv);
+    return E_NOINTERFACE;
+}
+
+static ULONG WINAPI QueryInfo_fnAddRef(IQueryInfo *iface)
+{
+    IQueryInfoImpl *This = impl_from_IQueryInfo(iface);
+    ULONG ref = InterlockedIncrement(&This->ref);
+
+    TRACE("(%p) ref=%d\n", This, ref);
+    return ref;
+}
+
+static ULONG WINAPI QueryInfo_fnRelease(IQueryInfo *iface)
+{
+    IQueryInfoImpl *This = impl_from_IQueryInfo(iface);
+    ULONG ref = InterlockedDecrement(&This->ref);
+
+    TRACE("(%p) ref=%d\n", This, ref);
+
+    if (!ref) {
+        SHFree(This->pidl);
+        HeapFree(GetProcessHeap(), 0, This);
+    }
+    return ref;
+}
+
+static HRESULT WINAPI QueryInfo_fnGetInfoTip(IQueryInfo *iface, DWORD flags, PWSTR *result)
+{
+    IQueryInfoImpl *This = impl_from_IQueryInfo(iface);
+
+    FIXME("(%p)->(0x%x, %p) stub\n", This, flags, result);
+
+    *result = NULL;
+    return S_OK;
+}
+
+static HRESULT WINAPI QueryInfo_fnGetFlags(IQueryInfo *iface, DWORD *flags)
+{
+    IQueryInfoImpl *This = impl_from_IQueryInfo(iface);
+
+    FIXME("(%p)->(%p) stub\n", This, flags);
+
+    *flags = 0;
+    return S_OK;
+}
+
+static const IQueryInfoVtbl IQueryInfo_vtbl =
+{
+    QueryInfo_fnQueryInterface,
+    QueryInfo_fnAddRef,
+    QueryInfo_fnRelease,
+    QueryInfo_fnGetInfoTip,
+    QueryInfo_fnGetFlags
+};
+
+
+HRESULT IQueryInfo_Constructor(LPCITEMIDLIST root, LPCITEMIDLIST item, void ** ppvOut)
+{
+    IQueryInfoImpl *qi = HeapAlloc(GetProcessHeap(), 0, sizeof(IQueryInfoImpl));
+    LPITEMIDLIST pidl = ILCombine(root, item);
+
+    if (!pidl || !qi) {
+        SHFree(pidl);
+        HeapFree(GetProcessHeap(), 0, qi);
+        return E_OUTOFMEMORY;
+    }
+
+    qi->IQueryInfo_iface.lpVtbl = &IQueryInfo_vtbl;
+    qi->ref = 1;
+    qi->pidl = ILClone(pidl);
+
+    SHFree(pidl);
+    if (!qi->pidl) {
+        HeapFree(GetProcessHeap(), 0, qi);
+        return E_OUTOFMEMORY;
+    }
+
+    *ppvOut = &qi->IQueryInfo_iface;
+
+    TRACE("==> %p (pidl: %p)\n", qi, qi->pidl);
+    return S_OK;
+}
diff --git a/dlls/shell32/shell32_main.h b/dlls/shell32/shell32_main.h
index ece1863..2c55685 100644
--- a/dlls/shell32/shell32_main.h
+++ b/dlls/shell32/shell32_main.h
@@ -112,6 +112,7 @@ HRESULT WINAPI ApplicationAssociationRegistration_Constructor(IUnknown *outer, R
 
 LPEXTRACTICONA	IExtractIconA_Constructor(LPCITEMIDLIST) DECLSPEC_HIDDEN;
 LPEXTRACTICONW	IExtractIconW_Constructor(LPCITEMIDLIST) DECLSPEC_HIDDEN;
+HRESULT IQueryInfo_Constructor(LPCITEMIDLIST, LPCITEMIDLIST, void **) DECLSPEC_HIDDEN;
 
 /* initialisation for FORMATETC */
 #define InitFormatEtc(fe, cf, med) \
diff --git a/dlls/shell32/shfldr_unixfs.c b/dlls/shell32/shfldr_unixfs.c
index b90fdfa..c15d0ce 100644
--- a/dlls/shell32/shfldr_unixfs.c
+++ b/dlls/shell32/shfldr_unixfs.c
@@ -1220,8 +1220,11 @@ static HRESULT WINAPI ShellFolder2_GetUIObjectOf(IShellFolder2* iface, HWND hwnd
     } else if (IsEqualIID(&IID_IShellLinkA, riid)) {
         FIXME("IShellLinkA\n");
         return E_FAIL;
-    } else {
-        FIXME("Unknown interface %s in GetUIObjectOf\n", debugstr_guid(riid));
+    } else if (IsEqualIID(&IID_IQueryInfo, riid)) {
+        if (cidl != 1) return E_INVALIDARG;
+        return IQueryInfo_Constructor(This->m_pidlLocation, apidl[0], ppvOut);
+     } else {
+        FIXME("Unknown interface %s\n", debugstr_guid(riid));
         return E_NOINTERFACE;
     }
 }
-- 
1.7.5.4




More information about the wine-patches mailing list