Signed-off-by: Hans Leidekker hans@codeweavers.com --- dlls/shell32/shell32_main.c | 112 +++++++++++++++++++++++++++++++++++- dlls/shell32/tests/appbar.c | 32 +++++++++++ 2 files changed, 143 insertions(+), 1 deletion(-)
diff --git a/dlls/shell32/shell32_main.c b/dlls/shell32/shell32_main.c index 99ee110b3d..034805f6fb 100644 --- a/dlls/shell32/shell32_main.c +++ b/dlls/shell32/shell32_main.c @@ -691,13 +691,123 @@ VOID WINAPI Printers_UnregisterWindow(HANDLE hClassPidl, HWND hwnd) FIXME("(%p, %p) stub!\n", hClassPidl, hwnd); }
+struct window_prop_store +{ + IPropertyStore IPropertyStore_iface; + LONG ref; +}; + +static inline struct window_prop_store *impl_from_IPropertyStore(IPropertyStore *iface) +{ + return CONTAINING_RECORD(iface, struct window_prop_store, IPropertyStore_iface); +} + +static ULONG WINAPI window_prop_store_AddRef(IPropertyStore *iface) +{ + struct window_prop_store *store = impl_from_IPropertyStore(iface); + LONG ref = InterlockedIncrement(&store->ref); + TRACE("returning %d\n", ref); + return ref; +} + +static ULONG WINAPI window_prop_store_Release(IPropertyStore *iface) +{ + struct window_prop_store *store = impl_from_IPropertyStore(iface); + LONG ref = InterlockedDecrement(&store->ref); + if (!ref) heap_free(store); + TRACE("returning %d\n", ref); + return ref; +} + +static HRESULT WINAPI window_prop_store_QueryInterface(IPropertyStore *iface, REFIID iid, void **obj) +{ + struct window_prop_store *store = impl_from_IPropertyStore(iface); + TRACE("%p, %s, %p\n", iface, debugstr_guid(iid), obj); + + if (!obj) return E_POINTER; + if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_IPropertyStore)) + { + *obj = &store->IPropertyStore_iface; + } + else + { + FIXME("no interface for %s\n", debugstr_guid(iid)); + *obj = NULL; + return E_NOINTERFACE; + } + + IUnknown_AddRef((IUnknown *)*obj); + return S_OK; +} + +static HRESULT WINAPI window_prop_store_GetCount(IPropertyStore *iface, DWORD *count) +{ + FIXME("%p, %p\n", iface, count); + return E_NOTIMPL; +} + +static HRESULT WINAPI window_prop_store_GetAt(IPropertyStore *iface, DWORD prop, PROPERTYKEY *key) +{ + FIXME("%p, %u,%p\n", iface, prop, key); + return E_NOTIMPL; +} + +static HRESULT WINAPI window_prop_store_GetValue(IPropertyStore *iface, const PROPERTYKEY *key, PROPVARIANT *var) +{ + FIXME("%p, {%s,%u}, %p\n", iface, debugstr_guid(&key->fmtid), key->pid, var); + return E_NOTIMPL; +} + +static HRESULT WINAPI window_prop_store_SetValue(IPropertyStore *iface, const PROPERTYKEY *key, const PROPVARIANT *var) +{ + FIXME("%p, {%s,%u}, %p\n", iface, debugstr_guid(&key->fmtid), key->pid, var); + return S_OK; +} + +static HRESULT WINAPI window_prop_store_Commit(IPropertyStore *iface) +{ + FIXME("%p\n", iface); + return S_OK; +} + +static const IPropertyStoreVtbl window_prop_store_vtbl = +{ + window_prop_store_QueryInterface, + window_prop_store_AddRef, + window_prop_store_Release, + window_prop_store_GetCount, + window_prop_store_GetAt, + window_prop_store_GetValue, + window_prop_store_SetValue, + window_prop_store_Commit +}; + +static HRESULT create_window_prop_store(IPropertyStore **obj) +{ + struct window_prop_store *store; + + if (!(store = heap_alloc(sizeof(*store)))) return E_OUTOFMEMORY; + store->IPropertyStore_iface.lpVtbl = &window_prop_store_vtbl; + store->ref = 1; + + *obj = &store->IPropertyStore_iface; + return S_OK; +} + /************************************************************************* * SHGetPropertyStoreForWindow [SHELL32.@] */ HRESULT WINAPI SHGetPropertyStoreForWindow(HWND hwnd, REFIID riid, void **ppv) { + IPropertyStore *store; + HRESULT hr; + FIXME("(%p %p %p) stub!\n", hwnd, riid, ppv); - return E_NOTIMPL; + + if ((hr = create_window_prop_store( &store )) != S_OK) return hr; + hr = IPropertyStore_QueryInterface( store, riid, ppv ); + IPropertyStore_Release( store ); + return hr; }
/*************************************************************************/ diff --git a/dlls/shell32/tests/appbar.c b/dlls/shell32/tests/appbar.c index 1505a40aeb..229d616c6f 100644 --- a/dlls/shell32/tests/appbar.c +++ b/dlls/shell32/tests/appbar.c @@ -21,6 +21,8 @@
#include <windows.h> #include "shellapi.h" +#define COBJMACROS +#include "propsys.h"
#include "wine/test.h"
@@ -30,6 +32,7 @@ static const CHAR testwindow_class[] = "testwindow";
static HMONITOR (WINAPI *pMonitorFromWindow)(HWND, DWORD); static HRESULT (WINAPI *pGetCurrentProcessExplicitAppUserModelID)(PWSTR*); +static HRESULT (WINAPI *pSHGetPropertyStoreForWindow)(HWND, REFIID, void **);
typedef BOOL (*boolean_function)(void);
@@ -433,6 +436,33 @@ todo_wine ok(appid == NULL, "got %p\n", appid); }
+static void test_SHGetPropertyStoreForWindow(void) +{ + HRESULT hr; + IUnknown *unk; + IPropertyStore *store = NULL; + + if (!pSHGetPropertyStoreForWindow) + { + win_skip("SHGetPropertyStoreForWindow() is not supported.\n"); + return; + } + + unk = (IUnknown *)0xdeadbeef; + hr = pSHGetPropertyStoreForWindow(GetDesktopWindow(), &IID_IDispatch, (void **)&unk); + ok(hr == E_NOINTERFACE, "got 0x%08x\n", hr); + ok(unk == NULL, "got %p\n", unk); + + hr = pSHGetPropertyStoreForWindow(GetDesktopWindow(), &IID_IUnknown, (void **)&unk); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = IUnknown_QueryInterface(unk, &IID_IPropertyStore, (void **)&store); + ok(hr == S_OK, "got 0x%08x\n", hr); + + if (store) IPropertyStore_Release(store); + if (unk) IUnknown_Release(unk); +} + START_TEST(appbar) { HMODULE huser32, hshell32; @@ -441,10 +471,12 @@ START_TEST(appbar) hshell32 = GetModuleHandleA("shell32.dll"); pMonitorFromWindow = (void*)GetProcAddress(huser32, "MonitorFromWindow"); pGetCurrentProcessExplicitAppUserModelID = (void*)GetProcAddress(hshell32, "GetCurrentProcessExplicitAppUserModelID"); + pSHGetPropertyStoreForWindow = (void*)GetProcAddress(hshell32, "SHGetPropertyStoreForWindow");
register_testwindow_class();
test_setpos(); test_appbarget(); test_GetCurrentProcessExplicitAppUserModelID(); + test_SHGetPropertyStoreForWindow(); }
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=58896
Your paranoid android.
=== debian10 (32 bit Chinese:China report) ===
shell32: shelllink.c:791: Test failed: save failed (0x80070020) shelllink.c:791: Test failed: got 0x00000001 shelllink.c:791: Test failed: Didn't expect NULL shelllink.c:506: Test failed: GetCurFile fails on shell32 < 5.0 shelllink.c:792: Test failed: GetDescription returned 'command on path without .exe' instead of 'non-executable file' shelllink.c:792: Test failed: GetWorkingDirectory returned 'C:\users\winetest\Temp\wct\shell32_test.exe' instead of 'C:\users\winetest\Temp' shelllink.c:792: Test failed: GetPath returned 'C:\users\winetest\Temp\wct\rundll32' instead of 'C:\users\winetest\Temp\test.txt' shelllink.c:792: Test failed: GetIconLocation returned 'C:\users\winetest\Temp\wct\shell32_test.exe' instead of 'C:\users\winetest\Temp\test.txt'