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
21 #include "combaseapi.h"
23 #include "uia_private.h"
25 #include "wine/debug.h"
27 WINE_DEFAULT_DEBUG_CHANNEL(uiautomation
);
31 struct uia_object_wrapper
33 IUnknown IUnknown_iface
;
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
);
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
);
70 IUnknown_Release(wrapper
->marshaler
);
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
;
93 TRACE("%p, %p\n", reserved
, ppv
);
95 wrapper
= calloc(1, sizeof(*wrapper
));
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
)))
109 hr
= IUnknown_QueryInterface(wrapper
->marshaler
, &IID_IMarshal
, ppv
);
110 IUnknown_Release(&wrapper
->IUnknown_iface
);
116 * UiaReservedNotSupportedValue/UiaReservedMixedAttributeValue object.
118 static HRESULT WINAPI
uia_reserved_obj_QueryInterface(IUnknown
*iface
,
119 REFIID riid
, void **ppv
)
122 if (IsEqualIID(riid
, &IID_IUnknown
))
124 else if (IsEqualIID(riid
, &IID_IMarshal
))
125 return create_uia_object_wrapper(iface
, ppv
);
127 return E_NOINTERFACE
;
132 static ULONG WINAPI
uia_reserved_obj_AddRef(IUnknown
*iface
)
137 static ULONG WINAPI
uia_reserved_obj_Release(IUnknown
*iface
)
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
;
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
)
169 if (IsEqualIID(riid
, &IID_IRawElementProviderSimple
) || IsEqualIID(riid
, &IID_IUnknown
))
172 return E_NOINTERFACE
;
174 IRawElementProviderSimple_AddRef(iface
);
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
);
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
);
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
;
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
);
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
);
227 case UIA_NativeWindowHandlePropertyId
:
228 V_VT(ret_val
) = VT_I4
;
229 V_I4(ret_val
) = HandleToUlong(host_prov
->hwnd
);
232 case UIA_ProviderDescriptionPropertyId
:
233 V_VT(ret_val
) = VT_BSTR
;
234 V_BSTR(ret_val
) = SysAllocString(L
"Wine: HWND Provider Proxy");
244 HRESULT WINAPI
hwnd_host_provider_get_HostRawElementProvider(IRawElementProviderSimple
*iface
,
245 IRawElementProviderSimple
**ret_val
)
247 TRACE("%p, %p\n", iface
, ret_val
);
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)
271 /***********************************************************************
272 * UiaGetReservedMixedAttributeValue (uiautomationcore.@)
274 HRESULT WINAPI
UiaGetReservedMixedAttributeValue(IUnknown
**value
)
276 TRACE("(%p)\n", value
);
281 *value
= &uia_reserved_ma_iface
;
286 /***********************************************************************
287 * UiaGetReservedNotSupportedValue (uiautomationcore.@)
289 HRESULT WINAPI
UiaGetReservedNotSupportedValue(IUnknown
**value
)
291 TRACE("(%p)\n", value
);
296 *value
= &uia_reserved_ns_iface
;
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));
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
);
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
);
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
);
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
));
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
);
361 HRESULT WINAPI
UiaHostProviderFromHwnd(HWND hwnd
, IRawElementProviderSimple
**provider
)
363 struct hwnd_host_provider
*host_prov
;
365 TRACE("(%p, %p)\n", hwnd
, provider
);
370 if (!IsWindow(hwnd
) || !provider
)
373 host_prov
= calloc(1, sizeof(*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
;
385 /***********************************************************************
386 * DllMain (uiautomationcore.@)
388 BOOL WINAPI
DllMain(HINSTANCE hinst
, DWORD reason
, void *reserved
)
390 TRACE("(%p, %ld, %p)\n", hinst
, reason
, reserved
);
394 case DLL_PROCESS_ATTACH
:
395 DisableThreadLibraryCalls(hinst
);
406 /* UIAutomation ClassFactory */
408 IClassFactory IClassFactory_iface
;
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
)
422 if (IsEqualIID(riid
, &IID_IClassFactory
) || IsEqualIID(riid
, &IID_IUnknown
))
425 return E_NOINTERFACE
;
427 IClassFactory_AddRef(iface
);
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
);
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
);
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
;
460 TRACE("%p, %p, %s, %p\n", iface
, pouter
, debugstr_guid(riid
), ppv
);
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
);
471 return E_NOINTERFACE
;
475 hr
= IUnknown_QueryInterface(obj
, riid
, ppv
);
476 IUnknown_Release(obj
);
482 static HRESULT WINAPI
uia_cf_LockServer(IClassFactory
*iface
, BOOL do_lock
)
484 FIXME("%p, %d: stub\n", iface
, do_lock
);
488 static const IClassFactoryVtbl uia_cf_Vtbl
=
490 uia_cf_QueryInterface
,
493 uia_cf_CreateInstance
,
497 static inline HRESULT
create_uia_cf(REFCLSID clsid
, REFIID riid
, void **ppv
)
499 struct uia_cf
*cf
= calloc(1, sizeof(*cf
));
504 return E_OUTOFMEMORY
;
506 cf
->IClassFactory_iface
.lpVtbl
= &uia_cf_Vtbl
;
510 hr
= IClassFactory_QueryInterface(&cf
->IClassFactory_iface
, riid
, ppv
);
511 IClassFactory_Release(&cf
->IClassFactory_iface
);
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
;