Module: wine Branch: master Commit: 61712ec79f3b5f92f5482b4dff73652e707d8e34 URL: https://gitlab.winehq.org/wine/wine/-/commit/61712ec79f3b5f92f5482b4dff73652...
Author: Connor McAdams cmcadams@codeweavers.com Date: Mon Jun 5 10:31:45 2023 -0400
uiautomationcore: Add support for cloning UiaCondition structures.
Signed-off-by: Connor McAdams cmcadams@codeweavers.com
---
dlls/uiautomationcore/uia_utils.c | 143 +++++++++++++++++++++++++++++++++++++- 1 file changed, 142 insertions(+), 1 deletion(-)
diff --git a/dlls/uiautomationcore/uia_utils.c b/dlls/uiautomationcore/uia_utils.c index 03416418cce..03fdef40e01 100644 --- a/dlls/uiautomationcore/uia_utils.c +++ b/dlls/uiautomationcore/uia_utils.c @@ -98,18 +98,159 @@ HRESULT get_interface_in_git(REFIID riid, DWORD git_cookie, IUnknown **ret_iface return S_OK; }
+/* + * UiaCondition cloning functions. + */ +static void uia_condition_destroy(struct UiaCondition *cond) +{ + if (!cond) + return; + + switch (cond->ConditionType) + { + case ConditionType_Property: + { + struct UiaPropertyCondition *prop_cond = (struct UiaPropertyCondition *)cond; + + VariantClear(&prop_cond->Value); + break; + } + + case ConditionType_Not: + { + struct UiaNotCondition *not_cond = (struct UiaNotCondition *)cond; + + uia_condition_destroy(not_cond->pConditions); + break; + } + + case ConditionType_And: + case ConditionType_Or: + { + struct UiaAndOrCondition *and_or_cond = (struct UiaAndOrCondition *)cond; + int i; + + for (i = 0; i < and_or_cond->cConditions; i++) + uia_condition_destroy(and_or_cond->ppConditions[i]); + heap_free(and_or_cond->ppConditions); + break; + } + + default: + break; + } + + heap_free(cond); +} + +static HRESULT uia_condition_clone(struct UiaCondition **dst, struct UiaCondition *src) +{ + HRESULT hr = S_OK; + + *dst = NULL; + switch (src->ConditionType) + { + case ConditionType_True: + case ConditionType_False: + if (!(*dst = heap_alloc_zero(sizeof(*dst)))) + return E_OUTOFMEMORY; + + (*dst)->ConditionType = src->ConditionType; + break; + + case ConditionType_Property: + { + struct UiaPropertyCondition *prop_cond = heap_alloc_zero(sizeof(*prop_cond)); + struct UiaPropertyCondition *src_cond = (struct UiaPropertyCondition *)src; + + if (!prop_cond) + return E_OUTOFMEMORY; + + *dst = (struct UiaCondition *)prop_cond; + prop_cond->ConditionType = ConditionType_Property; + prop_cond->PropertyId = src_cond->PropertyId; + prop_cond->Flags = src_cond->Flags; + VariantInit(&prop_cond->Value); + hr = VariantCopy(&prop_cond->Value, &src_cond->Value); + break; + } + + case ConditionType_Not: + { + struct UiaNotCondition *not_cond = heap_alloc_zero(sizeof(*not_cond)); + struct UiaNotCondition *src_cond = (struct UiaNotCondition *)src; + + if (!not_cond) + return E_OUTOFMEMORY; + + *dst = (struct UiaCondition *)not_cond; + not_cond->ConditionType = ConditionType_Not; + hr = uia_condition_clone(¬_cond->pConditions, src_cond->pConditions); + break; + } + + case ConditionType_And: + case ConditionType_Or: + { + struct UiaAndOrCondition *and_or_cond = heap_alloc_zero(sizeof(*and_or_cond)); + struct UiaAndOrCondition *src_cond = (struct UiaAndOrCondition *)src; + int i; + + if (!and_or_cond) + return E_OUTOFMEMORY; + + *dst = (struct UiaCondition *)and_or_cond; + and_or_cond->ConditionType = src_cond->ConditionType; + and_or_cond->ppConditions = heap_alloc_zero(sizeof(*and_or_cond->ppConditions) * src_cond->cConditions); + if (!and_or_cond->ppConditions) + { + hr = E_OUTOFMEMORY; + goto exit; + } + + and_or_cond->cConditions = src_cond->cConditions; + for (i = 0; i < src_cond->cConditions; i++) + { + hr = uia_condition_clone(&and_or_cond->ppConditions[i], src_cond->ppConditions[i]); + if (FAILED(hr)) + goto exit; + } + + break; + } + + default: + WARN("Tried to clone condition with invalid type %d\n", src->ConditionType); + return E_INVALIDARG; + } + +exit: + if (FAILED(hr)) + { + uia_condition_destroy(*dst); + *dst = NULL; + } + + return hr; +} + /* * UiaCacheRequest cloning functions. */ void uia_cache_request_destroy(struct UiaCacheRequest *cache_req) { + uia_condition_destroy(cache_req->pViewCondition); heap_free(cache_req->pProperties); heap_free(cache_req->pPatterns); }
HRESULT uia_cache_request_clone(struct UiaCacheRequest *dst, struct UiaCacheRequest *src) { - FIXME("Cache request condition cloning currently unimplemented\n"); + HRESULT hr; + + hr = uia_condition_clone(&dst->pViewCondition, src->pViewCondition); + if (FAILED(hr)) + return hr;
dst->Scope = src->Scope; dst->automationElementMode = src->automationElementMode;