[PATCH 2/5] explorer: Implement IShellWindows::Register() and IShellWindows::Revoke().
Zebediah Figura
z.figura12 at gmail.com
Sun May 17 23:29:41 CDT 2020
Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
---
dlls/shell32/tests/shelldispatch.c | 15 +----
programs/explorer/desktop.c | 93 ++++++++++++++++++++++++++++--
2 files changed, 90 insertions(+), 18 deletions(-)
diff --git a/dlls/shell32/tests/shelldispatch.c b/dlls/shell32/tests/shelldispatch.c
index c1e3fbcdaf1..eea505ff61d 100644
--- a/dlls/shell32/tests/shelldispatch.c
+++ b/dlls/shell32/tests/shelldispatch.c
@@ -1035,15 +1035,12 @@ static void test_ShellWindows(void)
ok(hr == HRESULT_FROM_WIN32(RPC_X_NULL_REF_POINTER), "got 0x%08x\n", hr);
hr = IShellWindows_Register(shellwindows, NULL, 0, SWC_EXPLORER, &cookie);
-todo_wine
ok(hr == E_POINTER, "got 0x%08x\n", hr);
hr = IShellWindows_Register(shellwindows, (IDispatch*)shellwindows, 0, SWC_EXPLORER, &cookie);
-todo_wine
ok(hr == E_POINTER, "got 0x%08x\n", hr);
hr = IShellWindows_Register(shellwindows, (IDispatch*)shellwindows, 0, SWC_EXPLORER, &cookie);
-todo_wine
ok(hr == E_POINTER, "got 0x%08x\n", hr);
hwnd = CreateWindowExA(0, "button", "test", BS_CHECKBOX | WS_VISIBLE | WS_POPUP,
@@ -1052,16 +1049,13 @@ todo_wine
cookie = 0;
hr = IShellWindows_Register(shellwindows, NULL, HandleToLong(hwnd), SWC_EXPLORER, &cookie);
-todo_wine {
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(cookie != 0, "got %d\n", cookie);
-}
+
cookie2 = 0;
hr = IShellWindows_Register(shellwindows, NULL, HandleToLong(hwnd), SWC_EXPLORER, &cookie2);
-todo_wine {
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(cookie2 != 0 && cookie2 != cookie, "got %d\n", cookie2);
-}
pidl = ILCreateFromPathA("C:\\");
V_VT(&v) = VT_ARRAY | VT_UI1;
@@ -1083,7 +1077,6 @@ todo_wine {
ok(!disp, "Got IDispatch %p.\n", &disp);
hr = IShellWindows_Revoke(shellwindows, cookie);
-todo_wine
ok(hr == S_OK, "got 0x%08x\n", hr);
hr = IShellWindows_FindWindowSW(shellwindows, &v, &v2, SWC_EXPLORER, &ret, 0, &disp);
@@ -1092,20 +1085,17 @@ todo_wine
ok(!disp, "Got IDispatch %p.\n", &disp);
hr = IShellWindows_Revoke(shellwindows, cookie2);
-todo_wine
ok(hr == S_OK, "got 0x%08x\n", hr);
hr = IShellWindows_Revoke(shellwindows, 0);
-todo_wine
ok(hr == S_FALSE, "got 0x%08x\n", hr);
/* we can register ourselves as desktop, but FindWindowSW still returns real desktop window */
cookie = 0;
hr = IShellWindows_Register(shellwindows, NULL, HandleToLong(hwnd), SWC_DESKTOP, &cookie);
-todo_wine {
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(cookie != 0, "got %d\n", cookie);
-}
+
disp = (void*)0xdeadbeef;
ret = 0xdead;
VariantInit(&v);
@@ -1235,7 +1225,6 @@ todo_wine
ok(ret == 0, "got %d\n", ret);
hr = IShellWindows_Revoke(shellwindows, cookie);
-todo_wine
ok(hr == S_OK, "got 0x%08x\n", hr);
DestroyWindow(hwnd);
IShellWindows_Release(shellwindows);
diff --git a/programs/explorer/desktop.c b/programs/explorer/desktop.c
index 8f515c045f3..137544567e4 100644
--- a/programs/explorer/desktop.c
+++ b/programs/explorer/desktop.c
@@ -118,9 +118,48 @@ static HRESULT get_typeinfo(tid_t tid, ITypeInfo **typeinfo)
return S_OK;
}
+static BOOL array_reserve(void **elements, unsigned int *capacity, unsigned int count, unsigned int size)
+{
+ unsigned int new_capacity, max_capacity;
+ void *new_elements;
+
+ if (count <= *capacity)
+ return TRUE;
+
+ max_capacity = ~(SIZE_T)0 / size;
+ if (count > max_capacity)
+ return FALSE;
+
+ new_capacity = max(4, *capacity);
+ while (new_capacity < count && new_capacity <= max_capacity / 2)
+ new_capacity *= 2;
+ if (new_capacity < count)
+ new_capacity = max_capacity;
+
+ if (!(new_elements = realloc(*elements, new_capacity * size)))
+ return FALSE;
+
+ *elements = new_elements;
+ *capacity = new_capacity;
+
+ return TRUE;
+}
+
+static LONG cookie_counter;
+
+struct window
+{
+ LONG cookie, hwnd;
+ int class;
+};
+
struct shellwindows
{
IShellWindows IShellWindows_iface;
+ CRITICAL_SECTION cs;
+
+ unsigned int count, max;
+ struct window *windows;
};
/* This is not limited to desktop itself, every file browser window that
@@ -1139,10 +1178,34 @@ static HRESULT WINAPI shellwindows__NewEnum(IShellWindows *iface, IUnknown **ppu
}
static HRESULT WINAPI shellwindows_Register(IShellWindows *iface,
- IDispatch *disp, LONG hWnd, int class, LONG *cookie)
+ IDispatch *disp, LONG hwnd, int class, LONG *cookie)
{
- FIXME("%p 0x%x 0x%x %p\n", disp, hWnd, class, cookie);
- return E_NOTIMPL;
+ struct shellwindows *sw = impl_from_IShellWindows(iface);
+ struct window *window;
+
+ TRACE("iface %p, disp %p, hwnd %#x, class %u, cookie %p.\n", iface, disp, hwnd, class, cookie);
+
+ if (!hwnd)
+ return E_POINTER;
+
+ if (disp)
+ FIXME("Ignoring IDispatch %p.\n", disp);
+
+ EnterCriticalSection(&sw->cs);
+
+ if (!array_reserve((void **)&sw->windows, &sw->max, sw->count + 1, sizeof(*sw->windows)))
+ {
+ LeaveCriticalSection(&sw->cs);
+ return E_OUTOFMEMORY;
+ }
+
+ window = &sw->windows[sw->count++];
+ window->hwnd = hwnd;
+ window->class = class;
+ *cookie = window->cookie = ++cookie_counter;
+
+ LeaveCriticalSection(&sw->cs);
+ return S_OK;
}
static HRESULT WINAPI shellwindows_RegisterPending(IShellWindows *iface,
@@ -1155,8 +1218,26 @@ static HRESULT WINAPI shellwindows_RegisterPending(IShellWindows *iface,
static HRESULT WINAPI shellwindows_Revoke(IShellWindows *iface, LONG cookie)
{
- FIXME("0x%x\n", cookie);
- return E_NOTIMPL;
+ struct shellwindows *sw = impl_from_IShellWindows(iface);
+ unsigned int i;
+
+ TRACE("iface %p, cookie %u.\n", iface, cookie);
+
+ EnterCriticalSection(&sw->cs);
+
+ for (i = 0; i < sw->count; ++i)
+ {
+ if (sw->windows[i].cookie == cookie)
+ {
+ --sw->count;
+ memmove(&sw->windows[i], &sw->windows[i + 1], (sw->count - i) * sizeof(*sw->windows));
+ LeaveCriticalSection(&sw->cs);
+ return S_OK;
+ }
+ }
+
+ LeaveCriticalSection(&sw->cs);
+ return S_FALSE;
}
static HRESULT WINAPI shellwindows_OnNavigate(IShellWindows *iface, LONG cookie, VARIANT *loc)
@@ -2156,6 +2237,8 @@ static void shellwindows_init(void)
CoInitialize(NULL);
shellwindows.IShellWindows_iface.lpVtbl = &shellwindowsvtbl;
+ InitializeCriticalSection(&shellwindows.cs);
+ shellwindows.cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": shellwindows.cs");
hr = CoRegisterClassObject(&CLSID_ShellWindows,
(IUnknown*)&shellwindows_classfactory.IClassFactory_iface,
--
2.26.2
More information about the wine-devel
mailing list