Commit 68aa92d6 authored by Connor McAdams's avatar Connor McAdams Committed by Alexandre Julliard

uiautomationcore: Add global interface table helper functions.

parent 3d0c9efc
...@@ -169,18 +169,6 @@ exit: ...@@ -169,18 +169,6 @@ exit:
} }
} }
static HRESULT get_global_interface_table(IGlobalInterfaceTable **git)
{
HRESULT hr;
hr = CoCreateInstance(&CLSID_StdGlobalInterfaceTable, NULL,
CLSCTX_INPROC_SERVER, &IID_IGlobalInterfaceTable, (void **)git);
if (FAILED(hr))
WARN("Failed to get GlobalInterfaceTable, hr %#lx\n", hr);
return hr;
}
static HWND get_hwnd_from_provider(IRawElementProviderSimple *elprov) static HWND get_hwnd_from_provider(IRawElementProviderSimple *elprov)
{ {
IRawElementProviderSimple *host_prov; IRawElementProviderSimple *host_prov;
...@@ -428,16 +416,8 @@ static ULONG WINAPI uia_node_Release(IWineUiaNode *iface) ...@@ -428,16 +416,8 @@ static ULONG WINAPI uia_node_Release(IWineUiaNode *iface)
{ {
if (node->git_cookie[i]) if (node->git_cookie[i])
{ {
IGlobalInterfaceTable *git; if (FAILED(unregister_interface_in_git(node->git_cookie[i])))
HRESULT hr; WARN("Failed to get revoke provider interface from GIT\n");
hr = get_global_interface_table(&git);
if (SUCCEEDED(hr))
{
hr = IGlobalInterfaceTable_RevokeInterfaceFromGlobal(git, node->git_cookie[i]);
if (FAILED(hr))
WARN("Failed to get revoke provider interface from Global Interface Table, hr %#lx\n", hr);
}
} }
if (node->prov[i]) if (node->prov[i])
...@@ -472,21 +452,13 @@ static HRESULT WINAPI uia_node_get_provider(IWineUiaNode *iface, int idx, IWineU ...@@ -472,21 +452,13 @@ static HRESULT WINAPI uia_node_get_provider(IWineUiaNode *iface, int idx, IWineU
prov_type = get_node_provider_type_at_idx(node, idx); prov_type = get_node_provider_type_at_idx(node, idx);
if (node->git_cookie[prov_type]) if (node->git_cookie[prov_type])
{ {
IGlobalInterfaceTable *git;
IWineUiaProvider *prov; IWineUiaProvider *prov;
HRESULT hr; HRESULT hr;
hr = get_global_interface_table(&git); hr = get_interface_in_git(&IID_IWineUiaProvider, node->git_cookie[prov_type], (IUnknown **)&prov);
if (FAILED(hr)) if (FAILED(hr))
return hr; return hr;
hr = IGlobalInterfaceTable_GetInterfaceFromGlobal(git, node->git_cookie[prov_type],
&IID_IWineUiaProvider, (void **)&prov);
if (FAILED(hr))
{
ERR("Failed to get provider interface from GlobalInterfaceTable, hr %#lx\n", hr);
return hr;
}
*out_prov = prov; *out_prov = prov;
} }
else else
...@@ -542,16 +514,8 @@ static HRESULT WINAPI uia_node_disconnect(IWineUiaNode *iface) ...@@ -542,16 +514,8 @@ static HRESULT WINAPI uia_node_disconnect(IWineUiaNode *iface)
prov_type = get_node_provider_type_at_idx(node, 0); prov_type = get_node_provider_type_at_idx(node, 0);
if (node->git_cookie[prov_type]) if (node->git_cookie[prov_type])
{ {
IGlobalInterfaceTable *git; if (FAILED(unregister_interface_in_git(node->git_cookie[prov_type])))
HRESULT hr; WARN("Failed to get revoke provider interface from GIT\n");
hr = get_global_interface_table(&git);
if (SUCCEEDED(hr))
{
hr = IGlobalInterfaceTable_RevokeInterfaceFromGlobal(git, node->git_cookie[prov_type]);
if (FAILED(hr))
WARN("Failed to get revoke provider interface from Global Interface Table, hr %#lx\n", hr);
}
node->git_cookie[prov_type] = 0; node->git_cookie[prov_type] = 0;
} }
...@@ -639,7 +603,6 @@ static HRESULT prepare_uia_node(struct uia_node *node) ...@@ -639,7 +603,6 @@ static HRESULT prepare_uia_node(struct uia_node *node)
for (i = 0; i < PROV_TYPE_COUNT; i++) for (i = 0; i < PROV_TYPE_COUNT; i++)
{ {
enum ProviderOptions prov_opts; enum ProviderOptions prov_opts;
IGlobalInterfaceTable *git;
struct uia_provider *prov; struct uia_provider *prov;
HRESULT hr; HRESULT hr;
...@@ -660,12 +623,8 @@ static HRESULT prepare_uia_node(struct uia_node *node) ...@@ -660,12 +623,8 @@ static HRESULT prepare_uia_node(struct uia_node *node)
*/ */
if (prov_opts & ProviderOptions_UseComThreading) if (prov_opts & ProviderOptions_UseComThreading)
{ {
hr = get_global_interface_table(&git); hr = register_interface_in_git((IUnknown *)&prov->IWineUiaProvider_iface, &IID_IWineUiaProvider,
if (FAILED(hr)) &node->git_cookie[i]);
return hr;
hr = IGlobalInterfaceTable_RegisterInterfaceInGlobal(git, (IUnknown *)&prov->IWineUiaProvider_iface,
&IID_IWineUiaProvider, &node->git_cookie[i]);
if (FAILED(hr)) if (FAILED(hr))
return hr; return hr;
} }
...@@ -2260,7 +2219,6 @@ static HRESULT create_wine_uia_nested_node_provider(struct uia_node *node, LRESU ...@@ -2260,7 +2219,6 @@ static HRESULT create_wine_uia_nested_node_provider(struct uia_node *node, LRESU
{ {
IWineUiaProvider *provider_iface = NULL; IWineUiaProvider *provider_iface = NULL;
struct uia_nested_node_provider *prov; struct uia_nested_node_provider *prov;
IGlobalInterfaceTable *git;
IWineUiaNode *nested_node; IWineUiaNode *nested_node;
int prov_opts, prov_type; int prov_opts, prov_type;
DWORD git_cookie; DWORD git_cookie;
...@@ -2339,14 +2297,7 @@ static HRESULT create_wine_uia_nested_node_provider(struct uia_node *node, LRESU ...@@ -2339,14 +2297,7 @@ static HRESULT create_wine_uia_nested_node_provider(struct uia_node *node, LRESU
* We need to use the GIT on all nested node providers so that our * We need to use the GIT on all nested node providers so that our
* IWineUiaNode proxy is used in the correct apartment. * IWineUiaNode proxy is used in the correct apartment.
*/ */
hr = get_global_interface_table(&git); hr = register_interface_in_git((IUnknown *)(IUnknown *)&prov->IWineUiaProvider_iface,
if (FAILED(hr))
{
IWineUiaProvider_Release(&prov->IWineUiaProvider_iface);
return hr;
}
hr = IGlobalInterfaceTable_RegisterInterfaceInGlobal(git, (IUnknown *)&prov->IWineUiaProvider_iface,
&IID_IWineUiaProvider, &git_cookie); &IID_IWineUiaProvider, &git_cookie);
if (FAILED(hr)) if (FAILED(hr))
{ {
......
...@@ -179,6 +179,9 @@ HRESULT create_msaa_provider(IAccessible *acc, long child_id, HWND hwnd, BOOL kn ...@@ -179,6 +179,9 @@ HRESULT create_msaa_provider(IAccessible *acc, long child_id, HWND hwnd, BOOL kn
IRawElementProviderSimple **elprov) DECLSPEC_HIDDEN; IRawElementProviderSimple **elprov) DECLSPEC_HIDDEN;
/* uia_utils.c */ /* uia_utils.c */
HRESULT register_interface_in_git(IUnknown *iface, REFIID riid, DWORD *ret_cookie) DECLSPEC_HIDDEN;
HRESULT unregister_interface_in_git(DWORD git_cookie) DECLSPEC_HIDDEN;
HRESULT get_interface_in_git(REFIID riid, DWORD git_cookie, IUnknown **ret_iface) DECLSPEC_HIDDEN;
HRESULT get_safearray_dim_bounds(SAFEARRAY *sa, UINT dim, LONG *lbound, LONG *elems) DECLSPEC_HIDDEN; HRESULT get_safearray_dim_bounds(SAFEARRAY *sa, UINT dim, LONG *lbound, LONG *elems) DECLSPEC_HIDDEN;
HRESULT get_safearray_bounds(SAFEARRAY *sa, LONG *lbound, LONG *elems) DECLSPEC_HIDDEN; HRESULT get_safearray_bounds(SAFEARRAY *sa, LONG *lbound, LONG *elems) DECLSPEC_HIDDEN;
int uia_compare_safearrays(SAFEARRAY *sa1, SAFEARRAY *sa2, int prop_type) DECLSPEC_HIDDEN; int uia_compare_safearrays(SAFEARRAY *sa1, SAFEARRAY *sa2, int prop_type) DECLSPEC_HIDDEN;
...@@ -22,6 +22,82 @@ ...@@ -22,6 +22,82 @@
WINE_DEFAULT_DEBUG_CHANNEL(uiautomation); WINE_DEFAULT_DEBUG_CHANNEL(uiautomation);
/*
* Global interface table helper functions.
*/
static HRESULT get_global_interface_table(IGlobalInterfaceTable **git)
{
HRESULT hr;
hr = CoCreateInstance(&CLSID_StdGlobalInterfaceTable, NULL,
CLSCTX_INPROC_SERVER, &IID_IGlobalInterfaceTable, (void **)git);
if (FAILED(hr))
WARN("Failed to get GlobalInterfaceTable, hr %#lx\n", hr);
return hr;
}
HRESULT register_interface_in_git(IUnknown *iface, REFIID riid, DWORD *ret_cookie)
{
IGlobalInterfaceTable *git;
DWORD git_cookie;
HRESULT hr;
*ret_cookie = 0;
hr = get_global_interface_table(&git);
if (FAILED(hr))
return hr;
hr = IGlobalInterfaceTable_RegisterInterfaceInGlobal(git, iface, riid, &git_cookie);
if (FAILED(hr))
{
WARN("Failed to register interface in GlobalInterfaceTable, hr %#lx\n", hr);
return hr;
}
*ret_cookie = git_cookie;
return S_OK;
}
HRESULT unregister_interface_in_git(DWORD git_cookie)
{
IGlobalInterfaceTable *git;
HRESULT hr;
hr = get_global_interface_table(&git);
if (FAILED(hr))
return hr;
hr = IGlobalInterfaceTable_RevokeInterfaceFromGlobal(git, git_cookie);
if (FAILED(hr))
WARN("Failed to revoke interface from GlobalInterfaceTable, hr %#lx\n", hr);
return hr;
}
HRESULT get_interface_in_git(REFIID riid, DWORD git_cookie, IUnknown **ret_iface)
{
IGlobalInterfaceTable *git;
IUnknown *iface;
HRESULT hr;
hr = get_global_interface_table(&git);
if (FAILED(hr))
return hr;
hr = IGlobalInterfaceTable_GetInterfaceFromGlobal(git, git_cookie, riid, (void **)&iface);
if (FAILED(hr))
{
ERR("Failed to get interface from Global Interface Table, hr %#lx\n", hr);
return hr;
}
*ret_iface = iface;
return S_OK;
}
HRESULT get_safearray_dim_bounds(SAFEARRAY *sa, UINT dim, LONG *lbound, LONG *elems) HRESULT get_safearray_dim_bounds(SAFEARRAY *sa, UINT dim, LONG *lbound, LONG *elems)
{ {
LONG ubound; LONG ubound;
......
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