Andrew Nguyen : dxdiagn: Successfully copy to destination variants with an invalid type in IDxDiagContainer ::GetProp.
Alexandre Julliard
julliard at winehq.org
Tue Mar 23 12:12:51 CDT 2010
Module: wine
Branch: master
Commit: 5f1764c629f6cd5094a989472e1db05ec699a789
URL: http://source.winehq.org/git/wine.git/?a=commit;h=5f1764c629f6cd5094a989472e1db05ec699a789
Author: Andrew Nguyen <arethusa26 at 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:
More information about the wine-cvs
mailing list