Commit e8dd3ada authored by Connor McAdams's avatar Connor McAdams Committed by Alexandre Julliard

uiautomationcore: Add stub IUIAutomation implementation.

parent 88a1e949
......@@ -6,6 +6,7 @@ EXTRADLLFLAGS = -Wb,--prefer-native
C_SRCS = \
uia_client.c \
uia_com_client.c \
uia_ids.c \
uia_main.c \
uia_provider.c
......
......@@ -9629,6 +9629,60 @@ static void test_UiaFind(void)
CoUninitialize();
}
struct uia_com_classes {
const GUID *clsid;
const GUID *iid;
};
static const struct uia_com_classes com_classes[] = {
{ &CLSID_CUIAutomation, &IID_IUnknown },
{ &CLSID_CUIAutomation, &IID_IUIAutomation },
{ &CLSID_CUIAutomation8, &IID_IUnknown },
{ &CLSID_CUIAutomation8, &IID_IUIAutomation },
{ &CLSID_CUIAutomation8, &IID_IUIAutomation2 },
{ &CLSID_CUIAutomation8, &IID_IUIAutomation3 },
{ &CLSID_CUIAutomation8, &IID_IUIAutomation4 },
{ &CLSID_CUIAutomation8, &IID_IUIAutomation5 },
{ &CLSID_CUIAutomation8, &IID_IUIAutomation6 },
};
static void test_CUIAutomation(void)
{
HRESULT hr;
int i;
CoInitializeEx(NULL, COINIT_MULTITHREADED);
for (i = 0; i < ARRAY_SIZE(com_classes); i++)
{
IUnknown *iface = NULL;
hr = CoCreateInstance(com_classes[i].clsid, NULL, CLSCTX_INPROC_SERVER, com_classes[i].iid,
(void **)&iface);
if ((com_classes[i].clsid == &CLSID_CUIAutomation8) && (hr == REGDB_E_CLASSNOTREG))
{
win_skip("CLSID_CUIAutomation8 class not registered, skipping further tests.\n");
break;
}
else if ((com_classes[i].clsid == &CLSID_CUIAutomation8) && (hr == E_NOINTERFACE) &&
(com_classes[i].iid != &IID_IUIAutomation2) && (com_classes[i].iid != &IID_IUIAutomation) &&
(com_classes[i].iid != &IID_IUnknown))
{
win_skip("No object for clsid %s, iid %s, skipping further tests.\n", debugstr_guid(com_classes[i].clsid),
debugstr_guid(com_classes[i].iid));
break;
}
ok(hr == S_OK, "Failed to create interface for clsid %s, iid %s, hr %#lx\n",
debugstr_guid(com_classes[i].clsid), debugstr_guid(com_classes[i].iid), hr);
ok(!!iface, "iface == NULL\n");
IUnknown_Release(iface);
}
CoUninitialize();
}
/*
* Once a process returns a UI Automation provider with
* UiaReturnRawElementProvider it ends up in an implicit MTA until exit. This
......@@ -9695,6 +9749,7 @@ START_TEST(uiautomation)
test_UiaGetUpdatedCache();
test_UiaNavigate();
test_UiaFind();
test_CUIAutomation();
if (uia_dll)
{
pUiaProviderFromIAccessible = (void *)GetProcAddress(uia_dll, "UiaProviderFromIAccessible");
......
......@@ -412,3 +412,126 @@ BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, void *reserved)
return TRUE;
}
/* UIAutomation ClassFactory */
struct uia_cf {
IClassFactory IClassFactory_iface;
LONG ref;
const GUID *clsid;
};
static struct uia_cf *impl_from_IClassFactory(IClassFactory *iface)
{
return CONTAINING_RECORD(iface, struct uia_cf, IClassFactory_iface);
}
static HRESULT WINAPI uia_cf_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv)
{
*ppv = NULL;
if (IsEqualIID(riid, &IID_IClassFactory) || IsEqualIID(riid, &IID_IUnknown))
*ppv = iface;
else
return E_NOINTERFACE;
IClassFactory_AddRef(iface);
return S_OK;
}
static ULONG WINAPI uia_cf_AddRef(IClassFactory *iface)
{
struct uia_cf *cf = impl_from_IClassFactory(iface);
ULONG ref = InterlockedIncrement(&cf->ref);
TRACE("%p, refcount %ld\n", cf, ref);
return ref;
}
static ULONG WINAPI uia_cf_Release(IClassFactory *iface)
{
struct uia_cf *cf = impl_from_IClassFactory(iface);
ULONG ref = InterlockedDecrement(&cf->ref);
TRACE("%p, refcount %ld\n", cf, ref);
if (!ref)
heap_free(cf);
return ref;
}
static HRESULT WINAPI uia_cf_CreateInstance(IClassFactory *iface, IUnknown *pouter, REFIID riid, void **ppv)
{
struct uia_cf *cf = impl_from_IClassFactory(iface);
IUnknown *obj = NULL;
HRESULT hr;
TRACE("%p, %p, %s, %p\n", iface, pouter, debugstr_guid(riid), ppv);
*ppv = NULL;
if (pouter)
return CLASS_E_NOAGGREGATION;
if (IsEqualGUID(cf->clsid, &CLSID_CUIAutomation))
hr = create_uia_iface(&obj, FALSE);
else if (IsEqualGUID(cf->clsid, &CLSID_CUIAutomation8))
hr = create_uia_iface(&obj, TRUE);
else
return E_NOINTERFACE;
if (SUCCEEDED(hr))
{
hr = IUnknown_QueryInterface(obj, riid, ppv);
IUnknown_Release(obj);
}
return hr;
}
static HRESULT WINAPI uia_cf_LockServer(IClassFactory *iface, BOOL do_lock)
{
FIXME("%p, %d: stub\n", iface, do_lock);
return S_OK;
}
static const IClassFactoryVtbl uia_cf_Vtbl =
{
uia_cf_QueryInterface,
uia_cf_AddRef,
uia_cf_Release,
uia_cf_CreateInstance,
uia_cf_LockServer
};
static inline HRESULT create_uia_cf(REFCLSID clsid, REFIID riid, void **ppv)
{
struct uia_cf *cf = heap_alloc_zero(sizeof(*cf));
HRESULT hr;
*ppv = NULL;
if (!cf)
return E_OUTOFMEMORY;
cf->IClassFactory_iface.lpVtbl = &uia_cf_Vtbl;
cf->clsid = clsid;
cf->ref = 1;
hr = IClassFactory_QueryInterface(&cf->IClassFactory_iface, riid, ppv);
IClassFactory_Release(&cf->IClassFactory_iface);
return hr;
}
/***********************************************************************
* DllGetClassObject (uiautomationcore.@)
*/
HRESULT WINAPI DllGetClassObject(REFCLSID clsid, REFIID riid, void **ppv)
{
TRACE("(%s, %s, %p)\n", debugstr_guid(clsid), debugstr_guid(riid), ppv);
if (IsEqualGUID(clsid, &CLSID_CUIAutomation) || IsEqualGUID(clsid, &CLSID_CUIAutomation8))
return create_uia_cf(clsid, riid, ppv);
return CLASS_E_CLASSNOTAVAILABLE;
}
......@@ -104,6 +104,9 @@ int get_node_provider_type_at_idx(struct uia_node *node, int idx) DECLSPEC_HIDDE
HRESULT create_uia_node_from_elprov(IRawElementProviderSimple *elprov, HUIANODE *out_node,
BOOL get_hwnd_providers) DECLSPEC_HIDDEN;
/* uia_com_client.c */
HRESULT create_uia_iface(IUnknown **iface, BOOL is_cui8) DECLSPEC_HIDDEN;
/* uia_ids.c */
const struct uia_prop_info *uia_prop_info_from_id(PROPERTYID prop_id) DECLSPEC_HIDDEN;
const struct uia_pattern_info *uia_pattern_info_from_id(PATTERNID pattern_id) DECLSPEC_HIDDEN;
......
@ stdcall -private DllCanUnloadNow()
@ stub DllGetClassObject
@ stdcall -private DllGetClassObject(ptr ptr ptr)
@ stdcall -private DllRegisterServer()
@ stdcall -private DllUnregisterServer()
@ stub DockPattern_SetDockPosition
......
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