-- v2: propsys: Add PropVariantGetStringElem implementation.
From: Piotr Caban piotr@codeweavers.com
--- dlls/propsys/propsys.spec | 2 +- dlls/propsys/propvar.c | 49 ++++++++++++++++++++++++ dlls/propsys/tests/propsys.c | 73 ++++++++++++++++++++++++++++++++++++ include/propvarutil.h | 2 + 4 files changed, 125 insertions(+), 1 deletion(-)
diff --git a/dlls/propsys/propsys.spec b/dlls/propsys/propsys.spec index 6a608ca88c1..6a1a313f93b 100644 --- a/dlls/propsys/propsys.spec +++ b/dlls/propsys/propsys.spec @@ -102,7 +102,7 @@ @ stub PropVariantGetInt16Elem @ stub PropVariantGetInt32Elem @ stub PropVariantGetInt64Elem -@ stub PropVariantGetStringElem +@ stdcall PropVariantGetStringElem(ptr long ptr) @ stub PropVariantGetUInt16Elem @ stub PropVariantGetUInt32Elem @ stub PropVariantGetUInt64Elem diff --git a/dlls/propsys/propvar.c b/dlls/propsys/propvar.c index 7572c33821d..c5d86c0027c 100644 --- a/dlls/propsys/propvar.c +++ b/dlls/propsys/propvar.c @@ -1263,3 +1263,52 @@ HRESULT WINAPI VariantToPropVariant(const VARIANT *var, PROPVARIANT *propvar)
return S_OK; } + +HRESULT WINAPI PropVariantGetStringElem(const PROPVARIANT *propvar, ULONG idx, WCHAR **ret) +{ + const WCHAR *wstr; + + TRACE("propvar %p, idx %lu, ret %p, propvar->vt %#x.\n", propvar, idx, ret, propvar ? propvar->vt : 0); + + *ret = 0; + switch (propvar->vt) + { + case VT_BSTR: + if (idx != 0) return E_INVALIDARG; + wstr = propvar->bstrVal; + break; + case VT_LPWSTR: + if (idx != 0) return E_INVALIDARG; + wstr = propvar->pwszVal; + break; + case VT_BSTR | VT_VECTOR: + if (idx >= propvar->cabstr.cElems) return E_INVALIDARG; + wstr = propvar->cabstr.pElems[idx]; + break; + case VT_LPWSTR | VT_VECTOR: + if (idx >= propvar->calpwstr.cElems) return E_INVALIDARG; + wstr = propvar->calpwstr.pElems[idx]; + break; + case VT_BSTR | VT_ARRAY: + { + LONG l = idx; + HRESULT hr; + + if (SafeArrayGetDim(propvar->parray) != 1) return E_INVALIDARG; + /* bug in native implementation: ignore lower-bound when checking bounds */ + if (idx >= propvar->parray->rgsabound[0].cElements) return E_INVALIDARG; + hr = SafeArrayGetElement(propvar->parray, &l, &wstr); + if (FAILED(hr)) return hr; + break; + } + default: + return E_INVALIDARG; + } + + if (!wstr) wstr = L""; + *ret = CoTaskMemAlloc((wcslen(wstr) + 1) * sizeof(WCHAR)); + if (!*ret) + return E_OUTOFMEMORY; + wcscpy(*ret, wstr); + return S_OK; +} diff --git a/dlls/propsys/tests/propsys.c b/dlls/propsys/tests/propsys.c index 273c99524ea..76d6c866546 100644 --- a/dlls/propsys/tests/propsys.c +++ b/dlls/propsys/tests/propsys.c @@ -2722,6 +2722,78 @@ static void test_PropVariantToVariant(void) VariantClear(&var); }
+void test_PropVariantGetStringElem(void) +{ + const WCHAR *strings[] = { L"a", L"bc" }; + PROPVARIANT propvar; + WCHAR *wstr; + HRESULT hr; + LONG idx; + + propvar.vt = VT_I4; + propvar.lVal = 1; + wstr = (WCHAR*)0xdeadbeef; + hr = PropVariantGetStringElem(&propvar, 0, &wstr); + ok(hr == E_INVALIDARG, "PropVariantGetStringElem returned %#lx.\n", hr); + ok(!wstr, "wstr = %p\n", wstr); + + propvar.vt = VT_LPSTR; + propvar.pszVal = (char *)"test"; + hr = PropVariantGetStringElem(&propvar, 0, &wstr); + ok(hr == E_INVALIDARG, "PropVariantGetStringElem returned %#lx.\n", hr); + + propvar.vt = VT_BSTR; + propvar.pwszVal = NULL; + hr = PropVariantGetStringElem(&propvar, 0, &wstr); + ok(!hr, "PropVariantGetStringElem returned %#lx.\n", hr); + ok(!wstr[0], "wstr = %s\n", debugstr_w(wstr)); + + propvar.vt = VT_BSTR; + propvar.bstrVal = SysAllocString(L"test"); + hr = PropVariantGetStringElem(&propvar, 0, &wstr); + ok(!hr, "PropVariantGetStringElem returned %#lx.\n", hr); + ok(!wcscmp(wstr, L"test"), "wstr = %s\n", debugstr_w(wstr)); + CoTaskMemFree(wstr); + hr = PropVariantGetStringElem(&propvar, 1, &wstr); + ok(hr == E_INVALIDARG, "PropVariantGetStringElem returned %#lx.\n", hr); + PropVariantClear(&propvar); + + hr = InitPropVariantFromStringVector(strings, ARRAY_SIZE(strings), &propvar); + ok(hr == S_OK, "InitPropVariantFromStringAsVector failed %lx\n", hr); + ok(propvar.vt == (VT_VECTOR | VT_LPWSTR), "propvar.vt = %x\n", propvar.vt); + hr = PropVariantGetStringElem(&propvar, 0, &wstr); + ok(!hr, "PropVariantGetStringElem returned %#lx.\n", hr); + ok(!wcscmp(wstr, L"a"), "wstr = %s\n", debugstr_w(wstr)); + CoTaskMemFree(wstr); + hr = PropVariantGetStringElem(&propvar, 1, &wstr); + ok(!hr, "PropVariantGetStringElem returned %#lx.\n", hr); + ok(!wcscmp(wstr, L"bc"), "wstr = %s\n", debugstr_w(wstr)); + CoTaskMemFree(wstr); + hr = PropVariantGetStringElem(&propvar, 2, &wstr); + ok(hr == E_INVALIDARG, "PropVariantGetStringElem returned %#lx.\n", hr); + PropVariantClear(&propvar); + + propvar.vt = VT_BSTR | VT_ARRAY; + propvar.parray = SafeArrayCreateVector(VT_BSTR, 1, 2); + ok(propvar.parray != NULL, "SafeArrayCreate failed\n"); + idx = 1; + hr = SafeArrayPutElement(propvar.parray, &idx, SysAllocString(L"test")); + ok(!hr, "SafeArrayPutElement returned %#lx.\n", hr); + idx = 2; + hr = SafeArrayPutElement(propvar.parray, &idx, SysAllocString(L"abc")); + ok(!hr, "SafeArrayPutElement returned %#lx.\n", hr); + hr = PropVariantGetStringElem(&propvar, 0, &wstr); + ok(hr == DISP_E_BADINDEX, "PropVariantGetStringElem returned %#lx.\n", hr); + hr = PropVariantGetStringElem(&propvar, 1, &wstr); + ok(!hr, "PropVariantGetStringElem returned %#lx.\n", hr); + ok(!wcscmp(wstr, L"test"), "wstr = %s\n", debugstr_w(wstr)); + CoTaskMemFree(wstr); + /* function works incorrectry if lower-band != 0 */ + hr = PropVariantGetStringElem(&propvar, 2, &wstr); + ok(hr == E_INVALIDARG, "PropVariantGetStringElem returned %#lx.\n", hr); + PropVariantClear(&propvar); +} + START_TEST(propsys) { test_InitPropVariantFromGUIDAsString(); @@ -2753,4 +2825,5 @@ START_TEST(propsys) test_VariantToString(); test_VariantToPropVariant(); test_PropVariantToVariant(); + test_PropVariantGetStringElem(); } diff --git a/include/propvarutil.h b/include/propvarutil.h index 0c23c7caa70..e35d8c5d0d4 100644 --- a/include/propvarutil.h +++ b/include/propvarutil.h @@ -114,6 +114,8 @@ PSSTDAPI PropVariantToStringAlloc(REFPROPVARIANT propvarIn, WCHAR **ret); PSSTDAPI PropVariantToVariant(const PROPVARIANT *propvar, VARIANT *var); PSSTDAPI VariantToPropVariant(const VARIANT* var, PROPVARIANT* propvar);
+PSSTDAPI PropVariantGetStringElem(const PROPVARIANT *propvar, ULONG idx, WCHAR **ret); + #ifdef __cplusplus
HRESULT InitPropVariantFromBoolean(BOOL fVal, PROPVARIANT *ppropvar);
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=151000
Your paranoid android.
=== debian11b (64 bit WoW report) ===
user32: msg.c:6995: Test failed: SetFocus(hwnd) on a button: 3: the winevent_hook 0x8005 was expected, but got hook 0x0005 instead msg.c:6995: Test failed: SetFocus(hwnd) on a button: 3: the winevent_hook 0x8005 was expected, but got winevent_hook 0x0003 instead msg.c:6995: Test failed: SetFocus(hwnd) on a button: 3: the winevent_hook 0x8005 was expected, but got msg 0x030f instead msg.c:6995: Test failed: SetFocus(hwnd) on a button: 3: the winevent_hook 0x8005 was expected, but got msg 0x001c instead msg.c:6995: Test failed: SetFocus(hwnd) on a button: 3: the winevent_hook 0x8005 was expected, but got msg 0x0086 instead msg.c:6995: Test failed: SetFocus(hwnd) on a button: 3: the winevent_hook 0x8005 was expected, but got msg 0x0006 instead msg.c:6995: Test failed: SetFocus(hwnd) on a button: 3: the winevent_hook 0x8005 was expected, but got hook 0x0009 instead