Module: wine Branch: master Commit: 3bc59a4e9a7d5b76ff533304d4c56bd4e21c6ebd URL: https://gitlab.winehq.org/wine/wine/-/commit/3bc59a4e9a7d5b76ff533304d4c56bd...
Author: Connor McAdams cmcadams@codeweavers.com Date: Fri Feb 3 14:06:38 2023 -0500
uiautomationcore: Implement IUIAutomation::IntNativeArrayToSafeArray.
Signed-off-by: Connor McAdams cmcadams@codeweavers.com
---
dlls/uiautomationcore/tests/uiautomation.c | 40 ++++++++++++++++++++++++++++++ dlls/uiautomationcore/uia_com_client.c | 29 ++++++++++++++++++++-- 2 files changed, 67 insertions(+), 2 deletions(-)
diff --git a/dlls/uiautomationcore/tests/uiautomation.c b/dlls/uiautomationcore/tests/uiautomation.c index d5cfccf729f..1752682a5a7 100644 --- a/dlls/uiautomationcore/tests/uiautomation.c +++ b/dlls/uiautomationcore/tests/uiautomation.c @@ -10017,11 +10017,17 @@ exit: static void test_CUIAutomation_value_conversion(IUIAutomation *uia_iface) { static const VARTYPE invalid_int_vts[] = { VT_I8, VT_INT }; + int in_arr[3] = { 0xdeadbeef, 0xfeedbeef, 0x1337b33f }; int *out_arr, out_arr_count, i; + LONG lbound, ubound; SAFEARRAY *sa; VARTYPE vt; HRESULT hr; + UINT dims;
+ /* + * Conversion from VT_I4 SAFEARRAY to native int array. + */ for (i = 0; i < ARRAY_SIZE(invalid_int_vts); i++) { vt = invalid_int_vts[i]; @@ -10047,6 +10053,40 @@ static void test_CUIAutomation_value_conversion(IUIAutomation *uia_iface)
SafeArrayDestroy(sa); CoTaskMemFree(out_arr); + + /* + * Conversion from native int array to VT_I4 SAFEARRAY. + */ + sa = NULL; + hr = IUIAutomation_IntNativeArrayToSafeArray(uia_iface, in_arr, ARRAY_SIZE(in_arr), &sa); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = SafeArrayGetVartype(sa, &vt); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(vt == VT_I4, "Unexpected vt %d.\n", vt); + + dims = SafeArrayGetDim(sa); + ok(dims == 1, "Unexpected array dims %d\n", dims); + + hr = SafeArrayGetLBound(sa, 1, &lbound); + ok(hr == S_OK, "Failed to get LBound with hr %#lx\n", hr); + ok(lbound == 0, "Unexpected LBound %#lx\n", lbound); + + hr = SafeArrayGetUBound(sa, 1, &ubound); + ok(hr == S_OK, "Failed to get UBound with hr %#lx\n", hr); + ok(((ubound - lbound) + 1) == ARRAY_SIZE(in_arr), "Unexpected array size %#lx\n", ((ubound - lbound) + 1)); + + for (i = 0; i < ARRAY_SIZE(in_arr); i++) + { + LONG idx = lbound + i; + int tmp_val; + + hr = SafeArrayGetElement(sa, &idx, &tmp_val); + ok(hr == S_OK, "Failed to get element at idx %ld, hr %#lx\n", idx, hr); + ok(tmp_val == in_arr[i], "Expected %d at idx %d, got %d\n", in_arr[i], i, tmp_val); + } + + SafeArrayDestroy(sa); }
struct uia_com_classes { diff --git a/dlls/uiautomationcore/uia_com_client.c b/dlls/uiautomationcore/uia_com_client.c index e78fc4ee416..de01517948a 100644 --- a/dlls/uiautomationcore/uia_com_client.c +++ b/dlls/uiautomationcore/uia_com_client.c @@ -1366,8 +1366,33 @@ static HRESULT WINAPI uia_iface_RemoveAllEventHandlers(IUIAutomation6 *iface) static HRESULT WINAPI uia_iface_IntNativeArrayToSafeArray(IUIAutomation6 *iface, int *arr, int arr_count, SAFEARRAY **out_sa) { - FIXME("%p, %p, %d, %p: stub\n", iface, arr, arr_count, out_sa); - return E_NOTIMPL; + HRESULT hr = S_OK; + SAFEARRAY *sa; + int *sa_arr; + + TRACE("%p, %p, %d, %p\n", iface, arr, arr_count, out_sa); + + if (!out_sa || !arr || !arr_count) + return E_INVALIDARG; + + *out_sa = NULL; + if (!(sa = SafeArrayCreateVector(VT_I4, 0, arr_count))) + return E_OUTOFMEMORY; + + hr = SafeArrayAccessData(sa, (void **)&sa_arr); + if (FAILED(hr)) + goto exit; + + memcpy(sa_arr, arr, sizeof(*arr) * arr_count); + hr = SafeArrayUnaccessData(sa); + if (SUCCEEDED(hr)) + *out_sa = sa; + +exit: + if (FAILED(hr)) + SafeArrayDestroy(sa); + + return hr; }
static HRESULT WINAPI uia_iface_IntSafeArrayToNativeArray(IUIAutomation6 *iface, SAFEARRAY *sa, int **out_arr,