[PATCH 2/2] oleacc: Add IServiceProvider interface to default accessible objects.

Connor McAdams cmcadams at codeweavers.com
Mon Apr 25 11:18:36 CDT 2022


Signed-off-by: Connor McAdams <cmcadams at codeweavers.com>
---
 dlls/oleacc/client.c         | 47 ++++++++++++++++++++++++++++++++++++
 dlls/oleacc/oleacc_private.h |  1 +
 dlls/oleacc/tests/main.c     | 26 +++++++++-----------
 dlls/oleacc/window.c         | 47 ++++++++++++++++++++++++++++++++++++
 4 files changed, 107 insertions(+), 14 deletions(-)

diff --git a/dlls/oleacc/client.c b/dlls/oleacc/client.c
index 20993109d28..42d4e1ed19a 100644
--- a/dlls/oleacc/client.c
+++ b/dlls/oleacc/client.c
@@ -32,6 +32,7 @@ typedef struct {
     IAccessible IAccessible_iface;
     IOleWindow IOleWindow_iface;
     IEnumVARIANT IEnumVARIANT_iface;
+    IServiceProvider IServiceProvider_iface;
 
     LONG ref;
 
@@ -114,6 +115,8 @@ static HRESULT WINAPI Client_QueryInterface(IAccessible *iface, REFIID riid, voi
         *ppv = &This->IOleWindow_iface;
     }else if(IsEqualIID(riid, &IID_IEnumVARIANT)) {
         *ppv = &This->IEnumVARIANT_iface;
+    }else if(IsEqualIID(riid, &IID_IServiceProvider)) {
+        *ppv = &This->IServiceProvider_iface;
     }else {
         WARN("no interface: %s\n", debugstr_guid(riid));
         *ppv = NULL;
@@ -703,6 +706,49 @@ static const IEnumVARIANTVtbl ClientEnumVARIANTVtbl = {
     Client_EnumVARIANT_Clone
 };
 
+static inline Client* impl_from_Client_ServiceProvider(IServiceProvider *iface)
+{
+    return CONTAINING_RECORD(iface, Client, IServiceProvider_iface);
+}
+
+static HRESULT WINAPI Client_ServiceProvider_QueryInterface(IServiceProvider *iface, REFIID riid, void **ppv)
+{
+    Client *This = impl_from_Client_ServiceProvider(iface);
+    return IAccessible_QueryInterface(&This->IAccessible_iface, riid, ppv);
+}
+
+static ULONG WINAPI Client_ServiceProvider_AddRef(IServiceProvider *iface)
+{
+    Client *This = impl_from_Client_ServiceProvider(iface);
+    return IAccessible_AddRef(&This->IAccessible_iface);
+}
+
+static ULONG WINAPI Client_ServiceProvider_Release(IServiceProvider *iface)
+{
+    Client *This = impl_from_Client_ServiceProvider(iface);
+    return IAccessible_Release(&This->IAccessible_iface);
+}
+
+static HRESULT WINAPI Client_ServiceProvider_QueryService(IServiceProvider *iface, REFGUID guid_service,
+        REFIID riid, void **ppv)
+{
+    Client *This = impl_from_Client_ServiceProvider(iface);
+
+    TRACE("(%p)->(%s %s %p)\n", This, debugstr_guid(guid_service), debugstr_guid(riid), ppv);
+
+    if (IsEqualIID(guid_service, &IIS_IsOleaccProxy))
+        return IAccessible_QueryInterface(&This->IAccessible_iface, riid, ppv);
+
+    return E_INVALIDARG;
+}
+
+static const IServiceProviderVtbl ClientServiceProviderVtbl = {
+    Client_ServiceProvider_QueryInterface,
+    Client_ServiceProvider_AddRef,
+    Client_ServiceProvider_Release,
+    Client_ServiceProvider_QueryService
+};
+
 static void edit_init(Client *client)
 {
     client->role = ROLE_SYSTEM_TEXT;
@@ -872,6 +918,7 @@ HRESULT create_client_object(HWND hwnd, const IID *iid, void **obj)
     client->IAccessible_iface.lpVtbl = &ClientVtbl;
     client->IOleWindow_iface.lpVtbl = &ClientOleWindowVtbl;
     client->IEnumVARIANT_iface.lpVtbl = &ClientEnumVARIANTVtbl;
+    client->IServiceProvider_iface.lpVtbl = &ClientServiceProviderVtbl;
     client->ref = 1;
     client->hwnd = hwnd;
     client->enum_pos = 0;
diff --git a/dlls/oleacc/oleacc_private.h b/dlls/oleacc/oleacc_private.h
index a01fc3615fe..c91b1465a79 100644
--- a/dlls/oleacc/oleacc_private.h
+++ b/dlls/oleacc/oleacc_private.h
@@ -17,6 +17,7 @@
  */
 
 #include "oleacc_classes.h"
+#include "servprov.h"
 
 struct win_class_data {
     const WCHAR *name;
diff --git a/dlls/oleacc/tests/main.c b/dlls/oleacc/tests/main.c
index 2d6a6c4cc2c..167c2e23a6a 100644
--- a/dlls/oleacc/tests/main.c
+++ b/dlls/oleacc/tests/main.c
@@ -1419,21 +1419,19 @@ static void check_acc_proxy_service_(IAccessible *acc, int line)
     HRESULT hr;
 
     hr = IAccessible_QueryInterface(acc, &IID_IServiceProvider, (void **)&service);
-    todo_wine ok(hr == S_OK, "got %#lx\n", hr);
-    if (SUCCEEDED(hr))
-    {
-        hr = IServiceProvider_QueryService(service, &IIS_IsOleaccProxy, &IID_IUnknown, (void **)&unk);
-        ok(hr == S_OK, "got %#lx\n", hr);
-        ok(!!unk, "unk == NULL\n");
-        ok(iface_cmp(unk, (IUnknown*)acc), "unk != acc\n");
-        IUnknown_Release(unk);
+    ok(hr == S_OK, "got %#lx\n", hr);
 
-        unk = NULL;
-        hr = IServiceProvider_QueryService(service, &IID_IUnknown, &IID_IUnknown, (void **)&unk);
-        ok(hr == E_INVALIDARG, "got %#lx\n", hr);
-        ok(!unk, "unk != NULL\n");
-        IServiceProvider_Release(service);
-    }
+    hr = IServiceProvider_QueryService(service, &IIS_IsOleaccProxy, &IID_IUnknown, (void **)&unk);
+    ok(hr == S_OK, "got %#lx\n", hr);
+    ok(!!unk, "unk == NULL\n");
+    ok(iface_cmp(unk, (IUnknown*)acc), "unk != acc\n");
+    IUnknown_Release(unk);
+
+    unk = NULL;
+    hr = IServiceProvider_QueryService(service, &IID_IUnknown, &IID_IUnknown, (void **)&unk);
+    ok(hr == E_INVALIDARG, "got %#lx\n", hr);
+    ok(!unk, "unk != NULL\n");
+    IServiceProvider_Release(service);
 }
 
 static void test_CreateStdAccessibleObject_classes(void)
diff --git a/dlls/oleacc/window.c b/dlls/oleacc/window.c
index 470bfd5b362..e431b6475a8 100644
--- a/dlls/oleacc/window.c
+++ b/dlls/oleacc/window.c
@@ -30,6 +30,7 @@ typedef struct {
     IAccessible IAccessible_iface;
     IOleWindow IOleWindow_iface;
     IEnumVARIANT IEnumVARIANT_iface;
+    IServiceProvider IServiceProvider_iface;
 
     LONG ref;
 
@@ -55,6 +56,8 @@ static HRESULT WINAPI Window_QueryInterface(IAccessible *iface, REFIID riid, voi
         *ppv = &This->IOleWindow_iface;
     }else if(IsEqualIID(riid, &IID_IEnumVARIANT)) {
         *ppv = &This->IEnumVARIANT_iface;
+    }else if(IsEqualIID(riid, &IID_IServiceProvider)) {
+        *ppv = &This->IServiceProvider_iface;
     }else {
         WARN("no interface: %s\n", debugstr_guid(riid));
         *ppv = NULL;
@@ -444,6 +447,49 @@ static const IEnumVARIANTVtbl WindowEnumVARIANTVtbl = {
     Window_EnumVARIANT_Clone
 };
 
+static inline Window* impl_from_Window_ServiceProvider(IServiceProvider *iface)
+{
+    return CONTAINING_RECORD(iface, Window, IServiceProvider_iface);
+}
+
+static HRESULT WINAPI Window_ServiceProvider_QueryInterface(IServiceProvider *iface, REFIID riid, void **ppv)
+{
+    Window *This = impl_from_Window_ServiceProvider(iface);
+    return IAccessible_QueryInterface(&This->IAccessible_iface, riid, ppv);
+}
+
+static ULONG WINAPI Window_ServiceProvider_AddRef(IServiceProvider *iface)
+{
+    Window *This = impl_from_Window_ServiceProvider(iface);
+    return IAccessible_AddRef(&This->IAccessible_iface);
+}
+
+static ULONG WINAPI Window_ServiceProvider_Release(IServiceProvider *iface)
+{
+    Window *This = impl_from_Window_ServiceProvider(iface);
+    return IAccessible_Release(&This->IAccessible_iface);
+}
+
+static HRESULT WINAPI Window_ServiceProvider_QueryService(IServiceProvider *iface, REFGUID guid_service,
+        REFIID riid, void **ppv)
+{
+    Window *This = impl_from_Window_ServiceProvider(iface);
+
+    TRACE("(%p)->(%s %s %p)\n", This, debugstr_guid(guid_service), debugstr_guid(riid), ppv);
+
+    if (IsEqualIID(guid_service, &IIS_IsOleaccProxy))
+        return IAccessible_QueryInterface(&This->IAccessible_iface, riid, ppv);
+
+    return E_INVALIDARG;
+}
+
+static const IServiceProviderVtbl WindowServiceProviderVtbl = {
+    Window_ServiceProvider_QueryInterface,
+    Window_ServiceProvider_AddRef,
+    Window_ServiceProvider_Release,
+    Window_ServiceProvider_QueryService
+};
+
 static const struct win_class_data classes[] = {
     {WC_LISTBOXW,           0x10000, TRUE},
     {L"#32768",             0x10001, TRUE}, /* menu */
@@ -467,6 +513,7 @@ HRESULT create_window_object(HWND hwnd, const IID *iid, void **obj)
     window->IAccessible_iface.lpVtbl = &WindowVtbl;
     window->IOleWindow_iface.lpVtbl = &WindowOleWindowVtbl;
     window->IEnumVARIANT_iface.lpVtbl = &WindowEnumVARIANTVtbl;
+    window->IServiceProvider_iface.lpVtbl = &WindowServiceProviderVtbl;
     window->ref = 1;
     window->hwnd = hwnd;
 
-- 
2.25.1




More information about the wine-devel mailing list