Commit 61fa18aa authored by Connor McAdams's avatar Connor McAdams Committed by Alexandre Julliard

uiautomationcore: Implement UiaGetPropertyValue.

parent 7dc4a179
......@@ -20,6 +20,22 @@
import "oaidl.idl";
struct uia_prop_info {
const GUID *guid;
int prop_id;
int type;
};
[
object,
uuid(57865755-6c05-4522-98df-4ca658b768ef),
pointer_default(unique),
]
interface IWineUiaProvider : IUnknown
{
HRESULT get_prop_val([in]const struct uia_prop_info *prop_info, [out, retval]VARIANT *ret_val);
}
[
object,
uuid(bccb6799-d831-4057-bd50-6425823ff1a3),
......@@ -27,4 +43,5 @@ import "oaidl.idl";
]
interface IWineUiaNode : IUnknown
{
HRESULT get_provider([out, retval]IWineUiaProvider **out_prov);
}
......@@ -16,11 +16,7 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#define COBJMACROS
#include "uiautomation.h"
#include "initguid.h"
#include "uia_classes.h"
#include "uia_private.h"
#include "wine/debug.h"
#include "wine/heap.h"
......@@ -34,7 +30,7 @@ struct uia_node {
IWineUiaNode IWineUiaNode_iface;
LONG ref;
IRawElementProviderSimple *elprov;
IWineUiaProvider *prov;
};
static inline struct uia_node *impl_from_IWineUiaNode(IWineUiaNode *iface)
......@@ -71,17 +67,28 @@ static ULONG WINAPI uia_node_Release(IWineUiaNode *iface)
TRACE("%p, refcount %ld\n", node, ref);
if (!ref)
{
IRawElementProviderSimple_Release(node->elprov);
IWineUiaProvider_Release(node->prov);
heap_free(node);
}
return ref;
}
static HRESULT WINAPI uia_node_get_provider(IWineUiaNode *iface, IWineUiaProvider **out_prov)
{
struct uia_node *node = impl_from_IWineUiaNode(iface);
*out_prov = node->prov;
IWineUiaProvider_AddRef(node->prov);
return S_OK;
}
static const IWineUiaNodeVtbl uia_node_vtbl = {
uia_node_QueryInterface,
uia_node_AddRef,
uia_node_Release,
uia_node_get_provider,
};
static struct uia_node *unsafe_impl_from_IWineUiaNode(IWineUiaNode *iface)
......@@ -92,13 +99,103 @@ static struct uia_node *unsafe_impl_from_IWineUiaNode(IWineUiaNode *iface)
return CONTAINING_RECORD(iface, struct uia_node, IWineUiaNode_iface);
}
/*
* IWineUiaProvider interface.
*/
struct uia_provider {
IWineUiaProvider IWineUiaProvider_iface;
LONG ref;
IRawElementProviderSimple *elprov;
};
static inline struct uia_provider *impl_from_IWineUiaProvider(IWineUiaProvider *iface)
{
return CONTAINING_RECORD(iface, struct uia_provider, IWineUiaProvider_iface);
}
static HRESULT WINAPI uia_provider_QueryInterface(IWineUiaProvider *iface, REFIID riid, void **ppv)
{
*ppv = NULL;
if (IsEqualIID(riid, &IID_IWineUiaProvider) || IsEqualIID(riid, &IID_IUnknown))
*ppv = iface;
else
return E_NOINTERFACE;
IWineUiaProvider_AddRef(iface);
return S_OK;
}
static ULONG WINAPI uia_provider_AddRef(IWineUiaProvider *iface)
{
struct uia_provider *prov = impl_from_IWineUiaProvider(iface);
ULONG ref = InterlockedIncrement(&prov->ref);
TRACE("%p, refcount %ld\n", prov, ref);
return ref;
}
static ULONG WINAPI uia_provider_Release(IWineUiaProvider *iface)
{
struct uia_provider *prov = impl_from_IWineUiaProvider(iface);
ULONG ref = InterlockedDecrement(&prov->ref);
TRACE("%p, refcount %ld\n", prov, ref);
if (!ref)
{
IRawElementProviderSimple_Release(prov->elprov);
heap_free(prov);
}
return ref;
}
static HRESULT WINAPI uia_provider_get_prop_val(IWineUiaProvider *iface,
const struct uia_prop_info *prop_info, VARIANT *ret_val)
{
FIXME("%p, %p, %p: stub\n", iface, prop_info, ret_val);
return E_NOTIMPL;
}
static const IWineUiaProviderVtbl uia_provider_vtbl = {
uia_provider_QueryInterface,
uia_provider_AddRef,
uia_provider_Release,
uia_provider_get_prop_val,
};
static HRESULT create_wine_uia_provider(struct uia_node *node, IRawElementProviderSimple *elprov)
{
static const int supported_prov_opts = ProviderOptions_ServerSideProvider;
enum ProviderOptions prov_opts;
struct uia_provider *prov;
HRESULT hr;
hr = IRawElementProviderSimple_get_ProviderOptions(elprov, &prov_opts);
if (FAILED(hr))
return hr;
if (prov_opts & ~supported_prov_opts)
FIXME("Ignoring unsupported ProviderOption(s) %#x\n", prov_opts & ~supported_prov_opts);
prov = heap_alloc_zero(sizeof(*prov));
if (!prov)
return E_OUTOFMEMORY;
prov->IWineUiaProvider_iface.lpVtbl = &uia_provider_vtbl;
prov->elprov = elprov;
IRawElementProviderSimple_AddRef(elprov);
prov->ref = 1;
node->prov = &prov->IWineUiaProvider_iface;
return S_OK;
}
/***********************************************************************
* UiaNodeFromProvider (uiautomationcore.@)
*/
HRESULT WINAPI UiaNodeFromProvider(IRawElementProviderSimple *elprov, HUIANODE *huianode)
{
static const int supported_prov_opts = ProviderOptions_ServerSideProvider;
enum ProviderOptions prov_opts;
struct uia_node *node;
HRESULT hr;
......@@ -113,19 +210,14 @@ HRESULT WINAPI UiaNodeFromProvider(IRawElementProviderSimple *elprov, HUIANODE *
if (!node)
return E_OUTOFMEMORY;
hr = IRawElementProviderSimple_get_ProviderOptions(elprov, &prov_opts);
hr = create_wine_uia_provider(node, elprov);
if (FAILED(hr))
{
heap_free(node);
return hr;
}
if (prov_opts & ~supported_prov_opts)
FIXME("Ignoring unsupported ProviderOption(s) %#x\n", prov_opts & ~supported_prov_opts);
node->IWineUiaNode_iface.lpVtbl = &uia_node_vtbl;
node->elprov = elprov;
IRawElementProviderSimple_AddRef(elprov);
node->ref = 1;
*huianode = (void *)&node->IWineUiaNode_iface;
......@@ -148,3 +240,46 @@ BOOL WINAPI UiaNodeRelease(HUIANODE huianode)
IWineUiaNode_Release(&node->IWineUiaNode_iface);
return TRUE;
}
/***********************************************************************
* UiaGetPropertyValue (uiautomationcore.@)
*/
HRESULT WINAPI UiaGetPropertyValue(HUIANODE huianode, PROPERTYID prop_id, VARIANT *out_val)
{
struct uia_node *node = unsafe_impl_from_IWineUiaNode((IWineUiaNode *)huianode);
const struct uia_prop_info *prop_info;
IWineUiaProvider *prov;
HRESULT hr;
VARIANT v;
TRACE("(%p, %d, %p)\n", huianode, prop_id, out_val);
if (!node || !out_val)
return E_INVALIDARG;
V_VT(out_val) = VT_UNKNOWN;
UiaGetReservedNotSupportedValue(&V_UNKNOWN(out_val));
prop_info = uia_prop_info_from_id(prop_id);
if (!prop_info)
return E_INVALIDARG;
if (!prop_info->type)
{
FIXME("No type info for prop_id %d\n", prop_id);
return E_NOTIMPL;
}
hr = IWineUiaNode_get_provider(&node->IWineUiaNode_iface, &prov);
if (FAILED(hr))
return hr;
VariantInit(&v);
hr = IWineUiaProvider_get_prop_val(prov, prop_info, &v);
if (SUCCEEDED(hr) && V_VT(&v) != VT_EMPTY)
*out_val = v;
IWineUiaProvider_Release(prov);
return S_OK;
}
......@@ -16,20 +16,13 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#define COBJMACROS
#include "uiautomation.h"
#include "uia_private.h"
#include "ocidl.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(uiautomation);
struct uia_prop_info {
const GUID *guid;
int prop_id;
};
static int __cdecl uia_property_guid_compare(const void *a, const void *b)
{
const GUID *guid = a;
......@@ -216,6 +209,34 @@ static const struct uia_prop_info default_uia_properties[] = {
{ &FullDescription_Property_GUID, UIA_FullDescriptionPropertyId, },
};
static const int prop_id_idx[] = {
0xaa, 0x8b, 0x76, 0xa3, 0x3d, 0x0e, 0x9f, 0x08,
0x2e, 0x1e, 0x65, 0x00, 0x0a, 0x69, 0x2f, 0x1b,
0x68, 0x86, 0x3a, 0x88, 0x30, 0x3b, 0x52, 0x54,
0x01, 0x98, 0x14, 0x93, 0x04, 0x17, 0x58, 0x2d,
0xa4, 0x37, 0x38, 0x03, 0x24, 0x8f, 0x4f, 0x06,
0x7a, 0x45, 0x02, 0x84, 0x89, 0x55, 0x28, 0x75,
0x48, 0x8a, 0x09, 0x19, 0x4a, 0x07, 0x9e, 0x77,
0x15, 0x34, 0x74, 0x7f, 0x82, 0x16, 0x90, 0x5c,
0x1f, 0x4c, 0x0f, 0xa8, 0x42, 0x26, 0x35, 0x61,
0xac, 0x33, 0x18, 0x51, 0x81, 0x71, 0x9c, 0x50,
0x59, 0x6a, 0x21, 0x92, 0x7d, 0x80, 0x44, 0x3c,
0x83, 0x36, 0x96, 0x4d, 0x32, 0x8c, 0x0c, 0x7b,
0x46, 0x43, 0x87, 0xa1, 0x1c, 0x73, 0x6d, 0x67,
0x6b, 0x8e, 0x13, 0x6c, 0x85, 0x41, 0x94, 0x40,
0x78, 0x3e, 0x72, 0x53, 0x4e, 0x23, 0x2b, 0x11,
0x27, 0x2a, 0x62, 0x12, 0xa9, 0xad, 0x7e, 0x9b,
0x29, 0x64, 0x2c, 0x99, 0x20, 0x70, 0x39, 0x6e,
0xa0, 0x8d, 0xa7, 0x60, 0x49, 0x25, 0x5b, 0xa5,
0x22, 0x0d, 0x0b, 0x5f, 0x3f, 0x4b, 0x5e, 0x9d,
0x47, 0x31, 0x1d, 0x5d, 0x97, 0xa6, 0x66, 0xae,
0x9a, 0x91, 0xa2, 0x56, 0x95, 0x05, 0x63, 0x10,
0xab, 0x57, 0x6f, 0x1a, 0x7c, 0x5a, 0x79,
};
#define PROP_ID_MIN 30000
#define PROP_ID_MAX (PROP_ID_MIN + ARRAY_SIZE(default_uia_properties))
static const struct uia_prop_info *uia_prop_info_from_guid(const GUID *guid)
{
struct uia_prop_info *prop;
......@@ -227,6 +248,14 @@ static const struct uia_prop_info *uia_prop_info_from_guid(const GUID *guid)
return NULL;
}
const struct uia_prop_info *uia_prop_info_from_id(PROPERTYID prop_id)
{
if ((prop_id < PROP_ID_MIN) || (prop_id > PROP_ID_MAX))
return NULL;
return &default_uia_properties[prop_id_idx[prop_id - PROP_ID_MIN]];
}
/***********************************************************************
* UiaLookupId (uiautomationcore.@)
*/
......
......@@ -16,10 +16,8 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#define COBJMACROS
#include "initguid.h"
#include "uiautomation.h"
#include "uia_private.h"
#include "ocidl.h"
#include "wine/debug.h"
......@@ -359,12 +357,3 @@ HRESULT WINAPI UiaDisconnectProvider(IRawElementProviderSimple *provider)
FIXME("(%p): stub\n", provider);
return E_NOTIMPL;
}
/***********************************************************************
* UiaGetPropertyValue (uiautomationcore.@)
*/
HRESULT WINAPI UiaGetPropertyValue(HUIANODE huianode, PROPERTYID prop_id, VARIANT *out_val)
{
FIXME("(%p, %d, %p): stub\n", huianode, prop_id, out_val);
return E_NOTIMPL;
}
/*
* Copyright 2022 Connor McAdams for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#define COBJMACROS
#include "uiautomation.h"
#include "uia_classes.h"
const struct uia_prop_info *uia_prop_info_from_id(PROPERTYID prop_id) DECLSPEC_HIDDEN;
......@@ -16,9 +16,7 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#define COBJMACROS
#include "uiautomation.h"
#include "uia_private.h"
#include "ocidl.h"
#include "wine/debug.h"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment