Commit 59a62981 authored by Connor McAdams's avatar Connor McAdams Committed by Alexandre Julliard

uiautomationcore: Determine provider type for nested node providers.

parent edcd55ba
...@@ -4988,7 +4988,7 @@ static const struct prov_method_sequence node_from_hwnd3[] = { ...@@ -4988,7 +4988,7 @@ static const struct prov_method_sequence node_from_hwnd3[] = {
{ &Provider, PROV_GET_HOST_RAW_ELEMENT_PROVIDER }, { &Provider, PROV_GET_HOST_RAW_ELEMENT_PROVIDER },
{ &Provider, FRAG_NAVIGATE, METHOD_TODO }, /* NavigateDirection_Parent */ { &Provider, FRAG_NAVIGATE, METHOD_TODO }, /* NavigateDirection_Parent */
{ &Provider, PROV_GET_PROVIDER_OPTIONS }, { &Provider, PROV_GET_PROVIDER_OPTIONS },
{ &Provider, PROV_GET_PROVIDER_OPTIONS, METHOD_TODO }, { &Provider, PROV_GET_PROVIDER_OPTIONS },
{ &Provider, PROV_GET_PROPERTY_VALUE, METHOD_TODO }, /* UIA_ProviderDescriptionPropertyId */ { &Provider, PROV_GET_PROPERTY_VALUE, METHOD_TODO }, /* UIA_ProviderDescriptionPropertyId */
{ 0 } { 0 }
}; };
...@@ -5040,7 +5040,7 @@ static const struct prov_method_sequence node_from_hwnd6[] = { ...@@ -5040,7 +5040,7 @@ static const struct prov_method_sequence node_from_hwnd6[] = {
{ &Provider_child, FRAG_GET_FRAGMENT_ROOT, METHOD_OPTIONAL }, { &Provider_child, FRAG_GET_FRAGMENT_ROOT, METHOD_OPTIONAL },
{ &Provider, PROV_GET_HOST_RAW_ELEMENT_PROVIDER, METHOD_OPTIONAL }, { &Provider, PROV_GET_HOST_RAW_ELEMENT_PROVIDER, METHOD_OPTIONAL },
{ &Provider, PROV_GET_PROVIDER_OPTIONS, METHOD_OPTIONAL }, { &Provider, PROV_GET_PROVIDER_OPTIONS, METHOD_OPTIONAL },
{ &Provider_child, PROV_GET_PROVIDER_OPTIONS, METHOD_TODO }, { &Provider_child, PROV_GET_PROVIDER_OPTIONS },
/* Next two are only done on Win10v1809+. */ /* Next two are only done on Win10v1809+. */
{ &Provider_child, FRAG_GET_FRAGMENT_ROOT, METHOD_OPTIONAL }, { &Provider_child, FRAG_GET_FRAGMENT_ROOT, METHOD_OPTIONAL },
{ &Provider, PROV_GET_HOST_RAW_ELEMENT_PROVIDER, METHOD_OPTIONAL }, { &Provider, PROV_GET_HOST_RAW_ELEMENT_PROVIDER, METHOD_OPTIONAL },
...@@ -5060,7 +5060,7 @@ static const struct prov_method_sequence node_from_hwnd7[] = { ...@@ -5060,7 +5060,7 @@ static const struct prov_method_sequence node_from_hwnd7[] = {
{ &Provider_child, PROV_GET_HOST_RAW_ELEMENT_PROVIDER }, { &Provider_child, PROV_GET_HOST_RAW_ELEMENT_PROVIDER },
{ &Provider_child, FRAG_NAVIGATE, METHOD_TODO }, /* NavigateDirection_Parent */ { &Provider_child, FRAG_NAVIGATE, METHOD_TODO }, /* NavigateDirection_Parent */
{ &Provider_child, PROV_GET_PROVIDER_OPTIONS }, { &Provider_child, PROV_GET_PROVIDER_OPTIONS },
{ &Provider_child, PROV_GET_PROVIDER_OPTIONS, METHOD_TODO }, { &Provider_child, PROV_GET_PROVIDER_OPTIONS },
{ &Provider, PROV_GET_PROVIDER_OPTIONS, METHOD_TODO }, { &Provider, PROV_GET_PROVIDER_OPTIONS, METHOD_TODO },
{ &Provider, PROV_GET_PROPERTY_VALUE, METHOD_OPTIONAL }, /* UIA_NativeWindowHandlePropertyId */ { &Provider, PROV_GET_PROPERTY_VALUE, METHOD_OPTIONAL }, /* UIA_NativeWindowHandlePropertyId */
{ &Provider, PROV_GET_HOST_RAW_ELEMENT_PROVIDER, METHOD_TODO }, { &Provider, PROV_GET_HOST_RAW_ELEMENT_PROVIDER, METHOD_TODO },
...@@ -5078,7 +5078,7 @@ static const struct prov_method_sequence node_from_hwnd8[] = { ...@@ -5078,7 +5078,7 @@ static const struct prov_method_sequence node_from_hwnd8[] = {
{ &Provider, PROV_GET_HOST_RAW_ELEMENT_PROVIDER }, { &Provider, PROV_GET_HOST_RAW_ELEMENT_PROVIDER },
{ &Provider, FRAG_NAVIGATE, METHOD_TODO }, /* NavigateDirection_Parent */ { &Provider, FRAG_NAVIGATE, METHOD_TODO }, /* NavigateDirection_Parent */
{ &Provider, PROV_GET_PROVIDER_OPTIONS }, { &Provider, PROV_GET_PROVIDER_OPTIONS },
{ &Provider, PROV_GET_PROVIDER_OPTIONS, METHOD_TODO }, { &Provider, PROV_GET_PROVIDER_OPTIONS },
{ &Provider, PROV_GET_PROPERTY_VALUE }, /* UIA_ProviderDescriptionPropertyId */ { &Provider, PROV_GET_PROPERTY_VALUE }, /* UIA_ProviderDescriptionPropertyId */
{ &Provider, PROV_GET_PROPERTY_VALUE, METHOD_TODO }, /* UIA_ControlTypePropertyId */ { &Provider, PROV_GET_PROPERTY_VALUE, METHOD_TODO }, /* UIA_ControlTypePropertyId */
{ 0 } { 0 }
......
...@@ -44,6 +44,7 @@ library UIA_wine_private ...@@ -44,6 +44,7 @@ library UIA_wine_private
interface IWineUiaProvider : IUnknown interface IWineUiaProvider : IUnknown
{ {
HRESULT get_prop_val([in]const struct uia_prop_info *prop_info, [out, retval]VARIANT *ret_val); HRESULT get_prop_val([in]const struct uia_prop_info *prop_info, [out, retval]VARIANT *ret_val);
HRESULT get_prov_opts([out, retval]int *out_opts);
} }
[ [
......
...@@ -333,6 +333,22 @@ int get_node_provider_type_at_idx(struct uia_node *node, int idx) ...@@ -333,6 +333,22 @@ int get_node_provider_type_at_idx(struct uia_node *node, int idx)
return 0; return 0;
} }
static HRESULT get_prov_opts_from_node_provider(IWineUiaNode *node, int idx, int *out_opts)
{
IWineUiaProvider *prov;
HRESULT hr;
*out_opts = 0;
hr = IWineUiaNode_get_provider(node, idx, &prov);
if (FAILED(hr))
return hr;
hr = IWineUiaProvider_get_prov_opts(prov, out_opts);
IWineUiaProvider_Release(prov);
return hr;
}
/* /*
* IWineUiaNode interface. * IWineUiaNode interface.
*/ */
...@@ -839,11 +855,28 @@ static HRESULT WINAPI uia_provider_get_prop_val(IWineUiaProvider *iface, ...@@ -839,11 +855,28 @@ static HRESULT WINAPI uia_provider_get_prop_val(IWineUiaProvider *iface,
return S_OK; return S_OK;
} }
static HRESULT WINAPI uia_provider_get_prov_opts(IWineUiaProvider *iface, int *out_opts)
{
struct uia_provider *prov = impl_from_IWineUiaProvider(iface);
enum ProviderOptions prov_opts;
HRESULT hr;
TRACE("%p, %p\n", iface, out_opts);
*out_opts = 0;
hr = IRawElementProviderSimple_get_ProviderOptions(prov->elprov, &prov_opts);
if (SUCCEEDED(hr))
*out_opts = prov_opts;
return S_OK;
}
static const IWineUiaProviderVtbl uia_provider_vtbl = { static const IWineUiaProviderVtbl uia_provider_vtbl = {
uia_provider_QueryInterface, uia_provider_QueryInterface,
uia_provider_AddRef, uia_provider_AddRef,
uia_provider_Release, uia_provider_Release,
uia_provider_get_prop_val, uia_provider_get_prop_val,
uia_provider_get_prov_opts,
}; };
static HRESULT create_wine_uia_provider(struct uia_node *node, IRawElementProviderSimple *elprov, static HRESULT create_wine_uia_provider(struct uia_node *node, IRawElementProviderSimple *elprov,
...@@ -1186,11 +1219,21 @@ static HRESULT WINAPI uia_nested_node_provider_get_prop_val(IWineUiaProvider *if ...@@ -1186,11 +1219,21 @@ static HRESULT WINAPI uia_nested_node_provider_get_prop_val(IWineUiaProvider *if
return S_OK; return S_OK;
} }
static HRESULT WINAPI uia_nested_node_provider_get_prov_opts(IWineUiaProvider *iface, int *out_opts)
{
struct uia_nested_node_provider *prov = impl_from_nested_node_IWineUiaProvider(iface);
TRACE("%p, %p\n", iface, out_opts);
return get_prov_opts_from_node_provider(prov->nested_node, 0, out_opts);
}
static const IWineUiaProviderVtbl uia_nested_node_provider_vtbl = { static const IWineUiaProviderVtbl uia_nested_node_provider_vtbl = {
uia_nested_node_provider_QueryInterface, uia_nested_node_provider_QueryInterface,
uia_nested_node_provider_AddRef, uia_nested_node_provider_AddRef,
uia_nested_node_provider_Release, uia_nested_node_provider_Release,
uia_nested_node_provider_get_prop_val, uia_nested_node_provider_get_prop_val,
uia_nested_node_provider_get_prov_opts,
}; };
static BOOL is_nested_node_provider(IWineUiaProvider *iface) static BOOL is_nested_node_provider(IWineUiaProvider *iface)
...@@ -1208,6 +1251,7 @@ static HRESULT create_wine_uia_nested_node_provider(struct uia_node *node, LRESU ...@@ -1208,6 +1251,7 @@ static HRESULT create_wine_uia_nested_node_provider(struct uia_node *node, LRESU
struct uia_nested_node_provider *prov; struct uia_nested_node_provider *prov;
IGlobalInterfaceTable *git; IGlobalInterfaceTable *git;
IWineUiaNode *nested_node; IWineUiaNode *nested_node;
int prov_opts, prov_type;
DWORD git_cookie; DWORD git_cookie;
HRESULT hr; HRESULT hr;
...@@ -1218,6 +1262,21 @@ static HRESULT create_wine_uia_nested_node_provider(struct uia_node *node, LRESU ...@@ -1218,6 +1262,21 @@ static HRESULT create_wine_uia_nested_node_provider(struct uia_node *node, LRESU
return hr; return hr;
} }
hr = get_prov_opts_from_node_provider(nested_node, 0, &prov_opts);
if (FAILED(hr))
{
WARN("Failed to get provider options for node %p with hr %#lx\n", nested_node, hr);
IWineUiaNode_Release(nested_node);
uia_stop_client_thread();
return hr;
}
/* Nested nodes can only serve as override or main providers. */
if (prov_opts & ProviderOptions_OverrideProvider)
prov_type = PROV_TYPE_OVERRIDE;
else
prov_type = PROV_TYPE_MAIN;
/* /*
* If we're retrieving a node from an HWND that belongs to the same thread * If we're retrieving a node from an HWND that belongs to the same thread
* as the client making the request, return a normal provider instead of a * as the client making the request, return a normal provider instead of a
...@@ -1276,8 +1335,8 @@ static HRESULT create_wine_uia_nested_node_provider(struct uia_node *node, LRESU ...@@ -1276,8 +1335,8 @@ static HRESULT create_wine_uia_nested_node_provider(struct uia_node *node, LRESU
} }
} }
node->prov[PROV_TYPE_MAIN] = provider_iface; node->prov[prov_type] = provider_iface;
node->git_cookie[PROV_TYPE_MAIN] = git_cookie; node->git_cookie[prov_type] = git_cookie;
node->prov_count++; node->prov_count++;
return S_OK; return S_OK;
......
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