Module: wine Branch: master Commit: 5f1764c629f6cd5094a989472e1db05ec699a789 URL: http://source.winehq.org/git/wine.git/?a=commit;h=5f1764c629f6cd5094a989472e...
Author: Andrew Nguyen arethusa26@gmail.com Date: Tue Mar 23 09:23:50 2010 -0500
dxdiagn: Successfully copy to destination variants with an invalid type in IDxDiagContainer::GetProp.
GetProp now simply unconditionally clears the destination variant if VariantClear fails.
---
dlls/dxdiagn/container.c | 9 ++++++--- dlls/dxdiagn/tests/Makefile.in | 2 +- dlls/dxdiagn/tests/container.c | 37 +++++++++++++++++++++++++++++++++++++ 3 files changed, 44 insertions(+), 4 deletions(-)
diff --git a/dlls/dxdiagn/container.c b/dlls/dxdiagn/container.c index db1a336..8585f7d 100644 --- a/dlls/dxdiagn/container.c +++ b/dlls/dxdiagn/container.c @@ -221,9 +221,12 @@ static HRESULT WINAPI IDxDiagContainerImpl_GetProp(PDXDIAGCONTAINER iface, LPCWS
p = This->properties; while (NULL != p) { - if (0 == lstrcmpW(p->vName, pwszPropName)) { - VariantCopy(pvarProp, &p->v); - return S_OK; + if (0 == lstrcmpW(p->vName, pwszPropName)) { + HRESULT hr = VariantClear(pvarProp); + if (hr == DISP_E_ARRAYISLOCKED || hr == DISP_E_BADVARTYPE) + VariantInit(pvarProp); + + return VariantCopy(pvarProp, &p->v); } p = p->next; } diff --git a/dlls/dxdiagn/tests/Makefile.in b/dlls/dxdiagn/tests/Makefile.in index 69f45fd..db75a4e 100644 --- a/dlls/dxdiagn/tests/Makefile.in +++ b/dlls/dxdiagn/tests/Makefile.in @@ -3,7 +3,7 @@ TOPOBJDIR = ../../.. SRCDIR = @srcdir@ VPATH = @srcdir@ TESTDLL = dxdiagn.dll -IMPORTS = ole32 kernel32 +IMPORTS = oleaut32 ole32 kernel32
C_SRCS = \ container.c \ diff --git a/dlls/dxdiagn/tests/container.c b/dlls/dxdiagn/tests/container.c index 214e7dd..6787c70 100644 --- a/dlls/dxdiagn/tests/container.c +++ b/dlls/dxdiagn/tests/container.c @@ -535,6 +535,8 @@ static void test_GetProp(void) IDxDiagContainer *child = NULL; DWORD count, index; VARIANT var; + SAFEARRAY *sa; + SAFEARRAYBOUND bound; static const WCHAR emptyW[] = {0}; static const WCHAR testW[] = {'t','e','s','t',0};
@@ -612,6 +614,41 @@ static void test_GetProp(void) ok(hr == E_INVALIDARG, "Expected IDxDiagContainer::GetProp to return E_INVALIDARG, got 0x%08x\n", hr); ok(V_VT(&var) == 0xdead, "Expected the variant to be untouched, got %u\n", V_VT(&var));
+ VariantInit(&var); + hr = IDxDiagContainer_GetProp(child, property, &var); + ok(hr == S_OK, "Expected IDxDiagContainer::GetProp to return S_OK, got 0x%08x\n", hr); + ok(V_VT(&var) != VT_EMPTY, "Expected the variant to be modified, got %d\n", V_VT(&var)); + + /* Since the documentation for IDxDiagContainer::GetProp claims that the + * function reports return values from VariantCopy, try to exercise failure + * paths in handling the destination variant. */ + + /* Try an invalid variant type. */ + V_VT(&var) = 0xdead; + hr = IDxDiagContainer_GetProp(child, property, &var); + ok(hr == S_OK, "Expected IDxDiagContainer::GetProp to return S_OK, got 0x%08x\n", hr); + ok(V_VT(&var) != 0xdead, "Expected the variant to be modified, got %d\n", V_VT(&var)); + + /* Try passing a variant with a locked SAFEARRAY. */ + bound.cElements = 1; + bound.lLbound = 0; + sa = SafeArrayCreate(VT_UI1, 1, &bound); + ok(sa != NULL, "Expected SafeArrayCreate to return a valid pointer\n"); + + V_VT(&var) = (VT_ARRAY | VT_UI1); + V_ARRAY(&var) = sa; + + hr = SafeArrayLock(sa); + ok(hr == S_OK, "Expected SafeArrayLock to return S_OK, got 0x%08x\n", hr); + + hr = IDxDiagContainer_GetProp(child, property, &var); + ok(hr == S_OK, "Expected IDxDiagContainer::GetProp to return S_OK, got 0x%08x\n", hr); + ok(V_VT(&var) != (VT_ARRAY | VT_UI1), "Expected the variant to be modified\n"); + + hr = SafeArrayUnlock(sa); + ok(hr == S_OK, "Expected SafeArrayUnlock to return S_OK, got 0x%08x\n", hr); + hr = SafeArrayDestroy(sa); + ok(hr == S_OK, "Expected SafeArrayDestroy to return S_OK, got 0x%08x\n", hr); IDxDiagContainer_Release(child);
cleanup: