windowscodecs: Silence fixme for IID_CMetaBitmapRenderTarget.
[wine.git] / dlls / uiautomationcore / uia_main.c
blob8c7a72bb35ed9e37381b83223202dad55df73c4b
1 /*
2 * Copyright 2017 Jacek Caban for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 #define COBJMACROS
21 #include "combaseapi.h"
22 #include "initguid.h"
23 #include "uia_private.h"
25 #include "wine/debug.h"
27 WINE_DEFAULT_DEBUG_CHANNEL(uiautomation);
29 HMODULE huia_module;
31 struct uia_object_wrapper
33 IUnknown IUnknown_iface;
34 LONG refcount;
36 IUnknown *marshaler;
37 IUnknown *marshal_object;
40 static struct uia_object_wrapper *impl_uia_object_wrapper_from_IUnknown(IUnknown *iface)
42 return CONTAINING_RECORD(iface, struct uia_object_wrapper, IUnknown_iface);
45 static HRESULT WINAPI uia_object_wrapper_QueryInterface(IUnknown *iface,
46 REFIID riid, void **ppv)
48 struct uia_object_wrapper *wrapper = impl_uia_object_wrapper_from_IUnknown(iface);
49 return IUnknown_QueryInterface(wrapper->marshal_object, riid, ppv);
52 static ULONG WINAPI uia_object_wrapper_AddRef(IUnknown *iface)
54 struct uia_object_wrapper *wrapper = impl_uia_object_wrapper_from_IUnknown(iface);
55 ULONG refcount = InterlockedIncrement(&wrapper->refcount);
57 TRACE("%p, refcount %ld\n", iface, refcount);
59 return refcount;
62 static ULONG WINAPI uia_object_wrapper_Release(IUnknown *iface)
64 struct uia_object_wrapper *wrapper = impl_uia_object_wrapper_from_IUnknown(iface);
65 ULONG refcount = InterlockedDecrement(&wrapper->refcount);
67 TRACE("%p, refcount %ld\n", iface, refcount);
68 if (!refcount)
70 IUnknown_Release(wrapper->marshaler);
71 free(wrapper);
74 return refcount;
77 static const IUnknownVtbl uia_object_wrapper_vtbl = {
78 uia_object_wrapper_QueryInterface,
79 uia_object_wrapper_AddRef,
80 uia_object_wrapper_Release,
84 * When passing the ReservedNotSupportedValue/ReservedMixedAttributeValue
85 * interface pointers across apartments within the same process, create a free
86 * threaded marshaler so that the pointer value is preserved.
88 static HRESULT create_uia_object_wrapper(IUnknown *reserved, void **ppv)
90 struct uia_object_wrapper *wrapper;
91 HRESULT hr;
93 TRACE("%p, %p\n", reserved, ppv);
95 wrapper = calloc(1, sizeof(*wrapper));
96 if (!wrapper)
97 return E_OUTOFMEMORY;
99 wrapper->IUnknown_iface.lpVtbl = &uia_object_wrapper_vtbl;
100 wrapper->marshal_object = reserved;
101 wrapper->refcount = 1;
103 if (FAILED(hr = CoCreateFreeThreadedMarshaler(&wrapper->IUnknown_iface, &wrapper->marshaler)))
105 free(wrapper);
106 return hr;
109 hr = IUnknown_QueryInterface(wrapper->marshaler, &IID_IMarshal, ppv);
110 IUnknown_Release(&wrapper->IUnknown_iface);
112 return hr;
116 * UiaReservedNotSupportedValue/UiaReservedMixedAttributeValue object.
118 static HRESULT WINAPI uia_reserved_obj_QueryInterface(IUnknown *iface,
119 REFIID riid, void **ppv)
121 *ppv = NULL;
122 if (IsEqualIID(riid, &IID_IUnknown))
123 *ppv = iface;
124 else if (IsEqualIID(riid, &IID_IMarshal))
125 return create_uia_object_wrapper(iface, ppv);
126 else
127 return E_NOINTERFACE;
129 return S_OK;
132 static ULONG WINAPI uia_reserved_obj_AddRef(IUnknown *iface)
134 return 1;
137 static ULONG WINAPI uia_reserved_obj_Release(IUnknown *iface)
139 return 1;
142 static const IUnknownVtbl uia_reserved_obj_vtbl = {
143 uia_reserved_obj_QueryInterface,
144 uia_reserved_obj_AddRef,
145 uia_reserved_obj_Release,
148 static IUnknown uia_reserved_ns_iface = {&uia_reserved_obj_vtbl};
149 static IUnknown uia_reserved_ma_iface = {&uia_reserved_obj_vtbl};
152 * UiaHostProviderFromHwnd IRawElementProviderSimple interface.
154 struct hwnd_host_provider {
155 IRawElementProviderSimple IRawElementProviderSimple_iface;
156 LONG refcount;
158 HWND hwnd;
161 static inline struct hwnd_host_provider *impl_from_hwnd_host_provider(IRawElementProviderSimple *iface)
163 return CONTAINING_RECORD(iface, struct hwnd_host_provider, IRawElementProviderSimple_iface);
166 HRESULT WINAPI hwnd_host_provider_QueryInterface(IRawElementProviderSimple *iface, REFIID riid, void **ppv)
168 *ppv = NULL;
169 if (IsEqualIID(riid, &IID_IRawElementProviderSimple) || IsEqualIID(riid, &IID_IUnknown))
170 *ppv = iface;
171 else
172 return E_NOINTERFACE;
174 IRawElementProviderSimple_AddRef(iface);
175 return S_OK;
178 ULONG WINAPI hwnd_host_provider_AddRef(IRawElementProviderSimple *iface)
180 struct hwnd_host_provider *host_prov = impl_from_hwnd_host_provider(iface);
181 ULONG refcount = InterlockedIncrement(&host_prov->refcount);
183 TRACE("%p, refcount %ld\n", iface, refcount);
185 return refcount;
188 ULONG WINAPI hwnd_host_provider_Release(IRawElementProviderSimple *iface)
190 struct hwnd_host_provider *host_prov = impl_from_hwnd_host_provider(iface);
191 ULONG refcount = InterlockedDecrement(&host_prov->refcount);
193 TRACE("%p, refcount %ld\n", iface, refcount);
195 if (!refcount)
196 free(host_prov);
198 return refcount;
201 HRESULT WINAPI hwnd_host_provider_get_ProviderOptions(IRawElementProviderSimple *iface,
202 enum ProviderOptions *ret_val)
204 TRACE("%p, %p\n", iface, ret_val);
205 *ret_val = ProviderOptions_ServerSideProvider;
206 return S_OK;
209 HRESULT WINAPI hwnd_host_provider_GetPatternProvider(IRawElementProviderSimple *iface,
210 PATTERNID pattern_id, IUnknown **ret_val)
212 TRACE("%p, %d, %p\n", iface, pattern_id, ret_val);
213 *ret_val = NULL;
214 return S_OK;
217 HRESULT WINAPI hwnd_host_provider_GetPropertyValue(IRawElementProviderSimple *iface,
218 PROPERTYID prop_id, VARIANT *ret_val)
220 struct hwnd_host_provider *host_prov = impl_from_hwnd_host_provider(iface);
222 TRACE("%p, %d, %p\n", iface, prop_id, ret_val);
224 VariantInit(ret_val);
225 switch (prop_id)
227 case UIA_NativeWindowHandlePropertyId:
228 V_VT(ret_val) = VT_I4;
229 V_I4(ret_val) = HandleToUlong(host_prov->hwnd);
230 break;
232 case UIA_ProviderDescriptionPropertyId:
233 V_VT(ret_val) = VT_BSTR;
234 V_BSTR(ret_val) = SysAllocString(L"Wine: HWND Provider Proxy");
235 break;
237 default:
238 break;
241 return S_OK;
244 HRESULT WINAPI hwnd_host_provider_get_HostRawElementProvider(IRawElementProviderSimple *iface,
245 IRawElementProviderSimple **ret_val)
247 TRACE("%p, %p\n", iface, ret_val);
248 *ret_val = NULL;
249 return S_OK;
252 static const IRawElementProviderSimpleVtbl hwnd_host_provider_vtbl = {
253 hwnd_host_provider_QueryInterface,
254 hwnd_host_provider_AddRef,
255 hwnd_host_provider_Release,
256 hwnd_host_provider_get_ProviderOptions,
257 hwnd_host_provider_GetPatternProvider,
258 hwnd_host_provider_GetPropertyValue,
259 hwnd_host_provider_get_HostRawElementProvider,
262 /***********************************************************************
263 * UiaClientsAreListening (uiautomationcore.@)
265 BOOL WINAPI UiaClientsAreListening(void)
267 TRACE("()\n");
268 return TRUE;
271 /***********************************************************************
272 * UiaGetReservedMixedAttributeValue (uiautomationcore.@)
274 HRESULT WINAPI UiaGetReservedMixedAttributeValue(IUnknown **value)
276 TRACE("(%p)\n", value);
278 if (!value)
279 return E_INVALIDARG;
281 *value = &uia_reserved_ma_iface;
283 return S_OK;
286 /***********************************************************************
287 * UiaGetReservedNotSupportedValue (uiautomationcore.@)
289 HRESULT WINAPI UiaGetReservedNotSupportedValue(IUnknown **value)
291 TRACE("(%p)\n", value);
293 if (!value)
294 return E_INVALIDARG;
296 *value = &uia_reserved_ns_iface;
298 return S_OK;
301 /***********************************************************************
302 * UiaRaiseAutomationPropertyChangedEvent (uiautomationcore.@)
304 HRESULT WINAPI UiaRaiseAutomationPropertyChangedEvent(IRawElementProviderSimple *provider, PROPERTYID id, VARIANT old, VARIANT new)
306 FIXME("(%p, %d, %s, %s): stub\n", provider, id, debugstr_variant(&old), debugstr_variant(&new));
307 return S_OK;
310 /***********************************************************************
311 * UiaRaiseStructureChangedEvent (uiautomationcore.@)
313 HRESULT WINAPI UiaRaiseStructureChangedEvent(IRawElementProviderSimple *provider, enum StructureChangeType struct_change_type,
314 int *runtime_id, int runtime_id_len)
316 FIXME("(%p, %d, %p, %d): stub\n", provider, struct_change_type, runtime_id, runtime_id_len);
317 return S_OK;
320 /***********************************************************************
321 * UiaRaiseAsyncContentLoadedEvent (uiautomationcore.@)
323 HRESULT WINAPI UiaRaiseAsyncContentLoadedEvent(IRawElementProviderSimple *provider,
324 enum AsyncContentLoadedState async_content_loaded_state, double percent_complete)
326 FIXME("(%p, %d, %f): stub\n", provider, async_content_loaded_state, percent_complete);
327 return S_OK;
330 /***********************************************************************
331 * UiaRaiseTextEditTextChangedEvent (uiautomationcore.@)
333 HRESULT WINAPI UiaRaiseTextEditTextChangedEvent(IRawElementProviderSimple *provider,
334 enum TextEditChangeType text_edit_change_type, SAFEARRAY *changed_data)
336 FIXME("(%p, %d, %p): stub\n", provider, text_edit_change_type, changed_data);
337 return S_OK;
340 /***********************************************************************
341 * UiaRaiseNotificationEvent (uiautomationcore.@)
343 HRESULT WINAPI UiaRaiseNotificationEvent(IRawElementProviderSimple *provider, enum NotificationKind notification_kind,
344 enum NotificationProcessing notification_processing, BSTR display_str, BSTR activity_id)
346 FIXME("(%p, %d, %d, %s, %s): stub\n", provider, notification_kind, notification_processing,
347 debugstr_w(display_str), debugstr_w(activity_id));
348 return S_OK;
351 /***********************************************************************
352 * UiaRaiseChangesEvent (uiautomationcore.@)
354 HRESULT WINAPI UiaRaiseChangesEvent(IRawElementProviderSimple *provider, int event_id_count,
355 struct UiaChangeInfo *uia_changes)
357 FIXME("(%p, %d, %p): stub\n", provider, event_id_count, uia_changes);
358 return S_OK;
361 HRESULT WINAPI UiaHostProviderFromHwnd(HWND hwnd, IRawElementProviderSimple **provider)
363 struct hwnd_host_provider *host_prov;
365 TRACE("(%p, %p)\n", hwnd, provider);
367 if (provider)
368 *provider = NULL;
370 if (!IsWindow(hwnd) || !provider)
371 return E_INVALIDARG;
373 host_prov = calloc(1, sizeof(*host_prov));
374 if (!host_prov)
375 return E_OUTOFMEMORY;
377 host_prov->IRawElementProviderSimple_iface.lpVtbl = &hwnd_host_provider_vtbl;
378 host_prov->refcount = 1;
379 host_prov->hwnd = hwnd;
380 *provider = &host_prov->IRawElementProviderSimple_iface;
382 return S_OK;
385 /***********************************************************************
386 * DllMain (uiautomationcore.@)
388 BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, void *reserved)
390 TRACE("(%p, %ld, %p)\n", hinst, reason, reserved);
392 switch (reason)
394 case DLL_PROCESS_ATTACH:
395 DisableThreadLibraryCalls(hinst);
396 huia_module = hinst;
397 break;
399 default:
400 break;
403 return TRUE;
406 /* UIAutomation ClassFactory */
407 struct uia_cf {
408 IClassFactory IClassFactory_iface;
409 LONG ref;
411 const GUID *clsid;
414 static struct uia_cf *impl_from_IClassFactory(IClassFactory *iface)
416 return CONTAINING_RECORD(iface, struct uia_cf, IClassFactory_iface);
419 static HRESULT WINAPI uia_cf_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv)
421 *ppv = NULL;
422 if (IsEqualIID(riid, &IID_IClassFactory) || IsEqualIID(riid, &IID_IUnknown))
423 *ppv = iface;
424 else
425 return E_NOINTERFACE;
427 IClassFactory_AddRef(iface);
428 return S_OK;
431 static ULONG WINAPI uia_cf_AddRef(IClassFactory *iface)
433 struct uia_cf *cf = impl_from_IClassFactory(iface);
434 ULONG ref = InterlockedIncrement(&cf->ref);
436 TRACE("%p, refcount %ld\n", cf, ref);
438 return ref;
441 static ULONG WINAPI uia_cf_Release(IClassFactory *iface)
443 struct uia_cf *cf = impl_from_IClassFactory(iface);
444 ULONG ref = InterlockedDecrement(&cf->ref);
446 TRACE("%p, refcount %ld\n", cf, ref);
448 if (!ref)
449 free(cf);
451 return ref;
454 static HRESULT WINAPI uia_cf_CreateInstance(IClassFactory *iface, IUnknown *pouter, REFIID riid, void **ppv)
456 struct uia_cf *cf = impl_from_IClassFactory(iface);
457 IUnknown *obj = NULL;
458 HRESULT hr;
460 TRACE("%p, %p, %s, %p\n", iface, pouter, debugstr_guid(riid), ppv);
462 *ppv = NULL;
463 if (pouter)
464 return CLASS_E_NOAGGREGATION;
466 if (IsEqualGUID(cf->clsid, &CLSID_CUIAutomation))
467 hr = create_uia_iface(&obj, FALSE);
468 else if (IsEqualGUID(cf->clsid, &CLSID_CUIAutomation8))
469 hr = create_uia_iface(&obj, TRUE);
470 else
471 return E_NOINTERFACE;
473 if (SUCCEEDED(hr))
475 hr = IUnknown_QueryInterface(obj, riid, ppv);
476 IUnknown_Release(obj);
479 return hr;
482 static HRESULT WINAPI uia_cf_LockServer(IClassFactory *iface, BOOL do_lock)
484 FIXME("%p, %d: stub\n", iface, do_lock);
485 return S_OK;
488 static const IClassFactoryVtbl uia_cf_Vtbl =
490 uia_cf_QueryInterface,
491 uia_cf_AddRef,
492 uia_cf_Release,
493 uia_cf_CreateInstance,
494 uia_cf_LockServer
497 static inline HRESULT create_uia_cf(REFCLSID clsid, REFIID riid, void **ppv)
499 struct uia_cf *cf = calloc(1, sizeof(*cf));
500 HRESULT hr;
502 *ppv = NULL;
503 if (!cf)
504 return E_OUTOFMEMORY;
506 cf->IClassFactory_iface.lpVtbl = &uia_cf_Vtbl;
507 cf->clsid = clsid;
508 cf->ref = 1;
510 hr = IClassFactory_QueryInterface(&cf->IClassFactory_iface, riid, ppv);
511 IClassFactory_Release(&cf->IClassFactory_iface);
513 return hr;
516 /***********************************************************************
517 * DllGetClassObject (uiautomationcore.@)
519 HRESULT WINAPI DllGetClassObject(REFCLSID clsid, REFIID riid, void **ppv)
521 TRACE("(%s, %s, %p)\n", debugstr_guid(clsid), debugstr_guid(riid), ppv);
523 if (IsEqualGUID(clsid, &CLSID_CUIAutomation) || IsEqualGUID(clsid, &CLSID_CUIAutomation8))
524 return create_uia_cf(clsid, riid, ppv);
526 return CLASS_E_CLASSNOTAVAILABLE;