From: Dmitry Timoshkov Subject: [3/4] ole32/tests: Add some tests for PropVariantCopy. Message-Id: <20140418181025.85b3056b.dmitry@baikal.ru> Date: Fri, 18 Apr 2014 18:10:25 +0900 --- dlls/ole32/ole2.c | 21 ++++++++---- dlls/ole32/tests/propvariant.c | 77 +++++++++++++++++++++++++++++++++++++----- 2 files changed, 83 insertions(+), 15 deletions(-) diff --git a/dlls/ole32/ole2.c b/dlls/ole32/ole2.c index 1228138..3849bad 100644 --- a/dlls/ole32/ole2.c +++ b/dlls/ole32/ole2.c @@ -3062,21 +3062,28 @@ HRESULT WINAPI PropVariantCopy(PROPVARIANT *pvarDest, /* [out] */ case VT_STREAMED_OBJECT: case VT_STORAGE: case VT_STORED_OBJECT: - IUnknown_AddRef((LPUNKNOWN)pvarDest->u.pStream); + if (pvarDest->u.pStream) + IStream_AddRef(pvarDest->u.pStream); break; case VT_CLSID: pvarDest->u.puuid = CoTaskMemAlloc(sizeof(CLSID)); *pvarDest->u.puuid = *pvarSrc->u.puuid; break; case VT_LPSTR: - len = strlen(pvarSrc->u.pszVal); - pvarDest->u.pszVal = CoTaskMemAlloc((len+1)*sizeof(CHAR)); - CopyMemory(pvarDest->u.pszVal, pvarSrc->u.pszVal, (len+1)*sizeof(CHAR)); + if (pvarSrc->u.pszVal) + { + len = strlen(pvarSrc->u.pszVal); + pvarDest->u.pszVal = CoTaskMemAlloc((len+1)*sizeof(CHAR)); + CopyMemory(pvarDest->u.pszVal, pvarSrc->u.pszVal, (len+1)*sizeof(CHAR)); + } break; case VT_LPWSTR: - len = lstrlenW(pvarSrc->u.pwszVal); - pvarDest->u.pwszVal = CoTaskMemAlloc((len+1)*sizeof(WCHAR)); - CopyMemory(pvarDest->u.pwszVal, pvarSrc->u.pwszVal, (len+1)*sizeof(WCHAR)); + if (pvarSrc->u.pwszVal) + { + len = lstrlenW(pvarSrc->u.pwszVal); + pvarDest->u.pwszVal = CoTaskMemAlloc((len+1)*sizeof(WCHAR)); + CopyMemory(pvarDest->u.pwszVal, pvarSrc->u.pwszVal, (len+1)*sizeof(WCHAR)); + } break; case VT_BLOB: case VT_BLOB_OBJECT: diff --git a/dlls/ole32/tests/propvariant.c b/dlls/ole32/tests/propvariant.c index 9863ced..390a4e1 100644 --- a/dlls/ole32/tests/propvariant.c +++ b/dlls/ole32/tests/propvariant.c @@ -130,7 +130,7 @@ static const char* wine_vtypes[VT_CLSID+1] = }; -static void expect(HRESULT hr, VARTYPE vt) +static void expect(HRESULT hr, VARTYPE vt, BOOL copy) { int idx = vt & VT_TYPEMASK; BYTE flags; @@ -158,7 +158,7 @@ static void expect(HRESULT hr, VARTYPE vt) } if(flags == PROP_INV) - ok(hr == STG_E_INVALIDPARAMETER, "%s (%s): got %08x\n", wine_vtypes[idx], modifier, hr); + ok(hr == copy ? DISP_E_BADVARTYPE : STG_E_INVALIDPARAMETER, "%s (%s): got %08x\n", wine_vtypes[idx], modifier, hr); else if(flags == PROP_V0) ok(hr == S_OK, "%s (%s): got %08x\n", wine_vtypes[idx], modifier, hr); else if(flags & PROP_TODO) @@ -180,9 +180,11 @@ static void expect(HRESULT hr, VARTYPE vt) static void test_validtypes(void) { - PROPVARIANT propvar; + PROPVARIANT propvar, copy, uninit; HRESULT hr; - unsigned int i; + unsigned int i, ret; + + memset(&uninit, 0x77, sizeof(uninit)); memset(&propvar, 0x55, sizeof(propvar)); hr = PropVariantClear(&propvar); @@ -206,8 +208,23 @@ static void test_validtypes(void) else U(propvar).pszVal = NULL; vt = propvar.vt = i; + memset(©, 0x77, sizeof(copy)); + hr = PropVariantCopy(©, &propvar); + expect(hr, vt, TRUE); + if (hr == S_OK) + { + ok(copy.vt == propvar.vt, "expected %d, got %d\n", propvar.vt, copy.vt); + ok(U(copy).uhVal.QuadPart == U(propvar).uhVal.QuadPart, "%u: expected %#x/%#x, got %#x/%#x\n", + i, U(propvar).uhVal.u.LowPart, U(propvar).uhVal.u.HighPart, + U(copy).uhVal.u.LowPart, U(copy).uhVal.u.HighPart); + } + else + { + ret = memcmp(©, &uninit, sizeof(copy)); + ok(!ret || broken(ret) /* win2000 */, "%d: copy should stay unchanged\n", i); + } hr = PropVariantClear(&propvar); - expect(hr, vt); + expect(hr, vt, FALSE); ok(propvar.vt == 0, "expected 0, got %d\n", propvar.vt); ok(U(propvar).uhVal.QuadPart == 0, "%u: expected 0, got %#x/%#x\n", i, U(propvar).uhVal.u.LowPart, U(propvar).uhVal.u.HighPart); @@ -215,8 +232,22 @@ static void test_validtypes(void) memset(&propvar, 0x55, sizeof(propvar)); U(propvar).pszVal = NULL; vt = propvar.vt = i | VT_ARRAY; + memset(©, 0x77, sizeof(copy)); + hr = PropVariantCopy(©, &propvar); + expect(hr, vt, TRUE); + if (hr == S_OK) + { + ok(copy.vt == propvar.vt, "expected %d, got %d\n", propvar.vt, copy.vt); + ok(U(copy).uhVal.QuadPart == 0, "%u: expected 0, got %#x/%#x\n", + i, U(copy).uhVal.u.LowPart, U(copy).uhVal.u.HighPart); + } + else + { + ret = memcmp(©, &uninit, sizeof(copy)); + ok(!ret || broken(ret) /* win2000 */, "%d: copy should stay unchanged\n", i); + } hr = PropVariantClear(&propvar); - expect(hr, vt); + expect(hr, vt, FALSE); ok(propvar.vt == 0, "expected 0, got %d\n", propvar.vt); ok(U(propvar).uhVal.QuadPart == 0, "%u: expected 0, got %#x/%#x\n", i, U(propvar).uhVal.u.LowPart, U(propvar).uhVal.u.HighPart); @@ -225,8 +256,23 @@ static void test_validtypes(void) U(propvar).caub.cElems = 0; U(propvar).caub.pElems = NULL; vt = propvar.vt = i | VT_VECTOR; + memset(©, 0x77, sizeof(copy)); + hr = PropVariantCopy(©, &propvar); + expect(hr, vt, TRUE); + if (hr == S_OK) + { + ok(copy.vt == propvar.vt, "expected %d, got %d\n", propvar.vt, copy.vt); + ok(!U(copy).caub.cElems, "%u: expected 0, got %d\n", i, U(copy).caub.cElems); +todo_wine + ok(!U(copy).caub.pElems, "%u: expected NULL, got %p\n", i, U(copy).caub.pElems); + } + else + { + ret = memcmp(©, &uninit, sizeof(copy)); + ok(!ret || broken(ret) /* win2000 */, "%d: copy should stay unchanged\n", i); + } hr = PropVariantClear(&propvar); - expect(hr, vt); + expect(hr, vt, FALSE); ok(propvar.vt == 0, "expected 0, got %d\n", propvar.vt); ok(U(propvar).uhVal.QuadPart == 0, "%u: expected 0, got %#x/%#x\n", i, U(propvar).uhVal.u.LowPart, U(propvar).uhVal.u.HighPart); @@ -234,8 +280,23 @@ static void test_validtypes(void) memset(&propvar, 0x55, sizeof(propvar)); U(propvar).pszVal = NULL; vt = propvar.vt = i | VT_BYREF; + memset(©, 0x77, sizeof(copy)); + hr = PropVariantCopy(©, &propvar); + expect(hr, vt, TRUE); + if (hr == S_OK) + { + ok(copy.vt == propvar.vt, "expected %d, got %d\n", propvar.vt, copy.vt); + ok(U(copy).uhVal.QuadPart == U(propvar).uhVal.QuadPart, "%u: expected %#x/%#x, got %#x/%#x\n", + i, U(propvar).uhVal.u.LowPart, U(propvar).uhVal.u.HighPart, + U(copy).uhVal.u.LowPart, U(copy).uhVal.u.HighPart); + } + else + { + ret = memcmp(©, &uninit, sizeof(copy)); + ok(!ret || broken(ret) /* win2000 */, "%d: copy should stay unchanged\n", i); + } hr = PropVariantClear(&propvar); - expect(hr, vt); + expect(hr, vt, FALSE); ok(propvar.vt == 0, "expected 0, got %d\n", propvar.vt); ok(U(propvar).uhVal.QuadPart == 0, "%u: expected 0, got %#x/%#x\n", i, U(propvar).uhVal.u.LowPart, U(propvar).uhVal.u.HighPart); -- 1.9.2