-- v2: propsys: Initially implement PropVariantToVariant. propsys: Support converting clsid to string for PropVariant. propsys/tests: Test converting clsid to string. propsys/tests: Add tests for PropVariantToVariant.
From: Ziqing Hui zhui@codeweavers.com
--- dlls/propsys/tests/propsys.c | 122 +++++++++++++++++++++++++++++++++++ 1 file changed, 122 insertions(+)
diff --git a/dlls/propsys/tests/propsys.c b/dlls/propsys/tests/propsys.c index fa0badef653..937a15fe3ff 100644 --- a/dlls/propsys/tests/propsys.c +++ b/dlls/propsys/tests/propsys.c @@ -45,6 +45,7 @@ DEFINE_GUID(DUMMY_GUID1, 0x12345678, 0x1234,0x1234, 0x12, 0x13, 0x14, 0x15, 0x16 static const char topic[] = "wine topic"; static const WCHAR topicW[] = {'w','i','n','e',' ','t','o','p','i','c',0}; static const WCHAR emptyW[] = {0}; +static const WCHAR dummy_guid_str[] = L"{DEADBEEF-DEAD-BEEF-DEAD-BEEFCAFEBABE}";
#define EXPECT_REF(obj,ref) _expect_ref((IUnknown *)obj, ref, __LINE__) static void _expect_ref(IUnknown *obj, ULONG ref, int line) @@ -2333,6 +2334,18 @@ static void test_VariantToString(void) "Unexpected propvar."#member" "format".\n", (propvar).member); \ } while (0)
+#define check_PropVariantToVariant(propvar, var, type, member, value, format) do \ +{ \ + (propvar).vt = VT_##type; \ + (propvar).member = (value); \ + hr = PropVariantToVariant(&(propvar), &(var)); \ + ok_(__FILE__, __LINE__)(hr == S_OK, "PropVariantToVariant returned %#lx.\n", hr); \ + ok_(__FILE__, __LINE__)(V_VT(&(var)) == VT_##type, "Unexpected vt %d.\n", V_VT(&(var))); \ + ok_(__FILE__, __LINE__)(V_##type(&(var)) == (value), \ + "Unexpected V_"#type"(&var) "format".\n", (propvar).member); \ +} while (0) + + static void test_VariantToPropVariant(void) { PROPVARIANT propvar; @@ -2396,6 +2409,114 @@ static void test_VariantToPropVariant(void) VariantClear(&var); }
+static void test_PropVariantToVariant(void) +{ + PROPVARIANT propvar; + VARIANT var; + HRESULT hr; + + VariantInit(&var); + PropVariantInit(&propvar); + + hr = PropVariantToVariant(NULL, &var); + todo_wine + ok(hr == E_INVALIDARG, "PropVariantToVariant returned %#lx.\n", hr); + hr = PropVariantToVariant(&propvar, NULL); + todo_wine + ok(hr == E_INVALIDARG, "PropVariantToVariant returned %#lx.\n", hr); + + propvar.vt = 0xdead; + hr = PropVariantToVariant(&propvar, &var); + todo_wine + ok(hr == E_OUTOFMEMORY, "PropVariantToVariant returned %#lx.\n", hr); + propvar.vt = VT_ILLEGAL; + hr = PropVariantToVariant(&propvar, &var); + todo_wine + ok(hr == E_OUTOFMEMORY, "PropVariantToVariant returned %#lx.\n", hr); + + propvar.vt = VT_EMPTY; + hr = PropVariantToVariant(&propvar, &var); + todo_wine + ok(hr == S_OK, "PropVariantToVariant returned %#lx.\n", hr); + ok(V_VT(&var) == VT_EMPTY, "Unexpected V_VT(&var) %d.\n", V_VT(&var)); + + propvar.vt = VT_NULL; + hr = PropVariantToVariant(&propvar, &var); + todo_wine + ok(hr == S_OK, "PropVariantToVariant returned %#lx.\n", hr); + todo_wine + ok(V_VT(&var) == VT_NULL, "Unexpected V_VT(&var) %d.\n", V_VT(&var)); + + todo_wine + { + check_PropVariantToVariant(propvar, var, I1, cVal, 'X', "%c"); + check_PropVariantToVariant(propvar, var, I2, iVal, -456, "%d"); + check_PropVariantToVariant(propvar, var, I4, lVal, -789, "%ld"); + check_PropVariantToVariant(propvar, var, I8, hVal.QuadPart, -101112, "%I64d"); + + check_PropVariantToVariant(propvar, var, UI1, bVal, 0xcd, "%#x"); + check_PropVariantToVariant(propvar, var, UI2, uiVal, 0xdead, "%#x"); + check_PropVariantToVariant(propvar, var, UI4, ulVal, 0xdeadbeef, "%#lx"); + check_PropVariantToVariant(propvar, var, UI8, uhVal.QuadPart, 0xdeadbeefdeadbeef, "%I64x"); + + check_PropVariantToVariant(propvar, var, BOOL, boolVal, TRUE, "%d"); + + check_PropVariantToVariant(propvar, var, R4, fltVal, 0.123f, "%f"); + check_PropVariantToVariant(propvar, var, R8, dblVal, 0.456f, "%f"); + } + + propvar.vt = VT_BSTR; + propvar.bstrVal = SysAllocString(L"test"); + hr = PropVariantToVariant(&propvar, &var); + todo_wine + ok(hr == S_OK, "PropVariantToVariant returned %#lx.\n", hr); + if (hr == S_OK) + { + ok(V_VT(&var) == VT_BSTR, "Unexpected V_VT(&var) %d.\n", V_VT(&var)); + ok(V_BSTR(&var) != propvar.bstrVal, "Got same string pointer.\n"); + ok(!wcscmp(V_BSTR(&var), propvar.bstrVal), "Unexpected V_BSTR(&var) %s.\n", debugstr_w(V_BSTR(&var))); + } + PropVariantClear(&propvar); + VariantClear(&var); + + propvar.vt = VT_CLSID; + propvar.puuid = (GUID *)&dummy_guid; + hr = PropVariantToVariant(&propvar, &var); + todo_wine + ok(hr == 39, "PropVariantToVariant returned %#lx.\n", hr); + if (hr == 39) + { + ok(V_VT(&var) == VT_BSTR, "Unexpected V_VT(&var) %d.\n", V_VT(&var)); + ok(!wcscmp(V_BSTR(&var), dummy_guid_str), "Unexpected V_BSTR(&var) %s.\n", debugstr_w(V_BSTR(&var))); + } + VariantClear(&var); + + propvar.vt = VT_LPSTR; + propvar.pszVal = (char *)topic; + hr = PropVariantToVariant(&propvar, &var); + todo_wine + ok(hr == S_OK, "PropVariantToVariant returned %#lx.\n", hr); + if (hr == S_OK) + { + ok(V_VT(&var) == VT_BSTR, "Unexpected V_VT(&var) %d.\n", V_VT(&var)); + ok(!wcscmp(V_BSTR(&var), topicW), "Unexpected V_BSTR(&var) %s.\n", debugstr_w(V_BSTR(&var))); + } + VariantClear(&var); + + propvar.vt = VT_LPWSTR; + propvar.pwszVal = (WCHAR *)topicW; + hr = PropVariantToVariant(&propvar, &var); + todo_wine + ok(hr == S_OK, "PropVariantToVariant returned %#lx.\n", hr); + if (hr == S_OK) + { + ok(V_VT(&var) == VT_BSTR, "Unexpected V_VT(&var) %d.\n", V_VT(&var)); + ok(V_BSTR(&var) != topicW, "Got same string pointer.\n"); + ok(!wcscmp(V_BSTR(&var), topicW), "Unexpected V_BSTR(&var) %s.\n", debugstr_w(V_BSTR(&var))); + } + VariantClear(&var); +} + START_TEST(propsys) { test_InitPropVariantFromGUIDAsString(); @@ -2425,4 +2546,5 @@ START_TEST(propsys) test_VariantToStringWithDefault(); test_VariantToString(); test_VariantToPropVariant(); + test_PropVariantToVariant(); }
From: Ziqing Hui zhui@codeweavers.com
--- dlls/propsys/tests/propsys.c | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-)
diff --git a/dlls/propsys/tests/propsys.c b/dlls/propsys/tests/propsys.c index 937a15fe3ff..2231bb2e16c 100644 --- a/dlls/propsys/tests/propsys.c +++ b/dlls/propsys/tests/propsys.c @@ -474,7 +474,7 @@ static void test_InitPropVariantFromGUIDAsString(void) const WCHAR *str; } testcases[] = { {&IID_NULL, L"{00000000-0000-0000-0000-000000000000}" }, - {&dummy_guid, L"{DEADBEEF-DEAD-BEEF-DEAD-BEEFCAFEBABE}" }, + {&dummy_guid, dummy_guid_str }, };
hres = InitPropVariantFromGUIDAsString(NULL, &propvar); @@ -663,6 +663,15 @@ static void test_PropVariantToStringAlloc(void) ok(hres == S_OK, "returned %lx\n", hres); ok(!lstrcmpW(str, emptyW), "got %s\n", wine_dbgstr_w(str)); CoTaskMemFree(str); + + prop.vt = VT_CLSID; + prop.puuid = (CLSID *)&dummy_guid; + hres = PropVariantToStringAlloc(&prop, &str); + todo_wine + ok(hres == S_OK, "PropVariantToStringAlloc returned %#lx.\n", hres); + if (hres == S_OK) + ok(!wcscmp(str, dummy_guid_str), "Unexpected str %s.\n", debugstr_w(str)); + CoTaskMemFree(str); }
static void test_PropVariantCompareEx(void) @@ -1303,6 +1312,11 @@ static void test_PropVariantToStringWithDefault(void) result = PropVariantToStringWithDefault(&propvar, default_value); ok(result == default_value, "Unexpected value %s\n", wine_dbgstr_w(result));
+ propvar.vt = VT_CLSID; + propvar.puuid = (CLSID *)&dummy_guid; + result = PropVariantToStringWithDefault(&propvar, default_value); + ok(result == default_value, "Unexpected value %s.\n", debugstr_w(result)); + /* VT_LPWSTR */
propvar.vt = VT_LPWSTR; @@ -1599,6 +1613,16 @@ static void test_PropVariantToString(void) ok(!lstrcmpW(bufferW, stringW), "got wrong string: "%s".\n", wine_dbgstr_w(bufferW)); memset(bufferW, 0, sizeof(bufferW)); SysFreeString(propvar.bstrVal); + + PropVariantInit(&propvar); + propvar.vt = VT_CLSID; + propvar.puuid = (CLSID *)&dummy_guid; + hr = PropVariantToString(&propvar, bufferW, ARRAY_SIZE(bufferW)); + todo_wine + ok(hr == S_OK, "PropVariantToString returned %#lx.\n", hr); + todo_wine + ok(!wcscmp(bufferW, dummy_guid_str), "Unexpected string %s.\n", debugstr_w(bufferW)); + memset(bufferW, 0, sizeof(bufferW)); }
static void test_PropVariantToBuffer(void)
From: Ziqing Hui zhui@codeweavers.com
--- dlls/propsys/propvar.c | 26 +++++++++++++++++--------- dlls/propsys/tests/propsys.c | 4 ---- 2 files changed, 17 insertions(+), 13 deletions(-)
diff --git a/dlls/propsys/propvar.c b/dlls/propsys/propvar.c index 6500926380f..c54fe868ee3 100644 --- a/dlls/propsys/propvar.c +++ b/dlls/propsys/propvar.c @@ -36,6 +36,7 @@
WINE_DEFAULT_DEBUG_CHANNEL(propsys);
+#define GUID_STR_LEN 38 static HRESULT VARIANT_ValidateType(VARTYPE vt) { VARTYPE vtExtra = vt & (VT_VECTOR | VT_ARRAY | VT_BYREF | VT_RESERVED); @@ -177,6 +178,13 @@ static HRESULT PROPVAR_ConvertNumber(REFPROPVARIANT pv, int dest_bits, return S_OK; }
+static void PROPVAR_GUIDToWSTR(REFGUID guid, WCHAR *str) +{ + swprintf(str, GUID_STR_LEN + 1, L"{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}", guid->Data1, + guid->Data2, guid->Data3, guid->Data4[0], guid->Data4[1], guid->Data4[2], + guid->Data4[3], guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]); +} + HRESULT WINAPI PropVariantToDouble(REFPROPVARIANT propvarIn, double *ret) { LONGLONG res; @@ -356,7 +364,6 @@ HRESULT WINAPI PropVariantToBuffer(REFPROPVARIANT propvarIn, void *ret, UINT cb) return hr; }
- HRESULT WINAPI PropVariantToString(REFPROPVARIANT propvarIn, PWSTR ret, UINT cch) { HRESULT hr; @@ -421,6 +428,15 @@ HRESULT WINAPI PropVariantToStringAlloc(REFPROPVARIANT propvarIn, WCHAR **ret) } break;
+ case VT_CLSID: + if (propvarIn->puuid) + { + if (!(res = CoTaskMemAlloc((GUID_STR_LEN + 1) * sizeof(WCHAR)))) + return E_OUTOFMEMORY; + PROPVAR_GUIDToWSTR(propvarIn->puuid, res); + } + break; + default: FIXME("Unsupported conversion (%d)\n", propvarIn->vt); hr = E_FAIL; @@ -654,14 +670,6 @@ HRESULT WINAPI PropVariantChangeType(PROPVARIANT *ppropvarDest, REFPROPVARIANT p return E_FAIL; } } - -static void PROPVAR_GUIDToWSTR(REFGUID guid, WCHAR *str) -{ - swprintf(str, 39, L"{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}", guid->Data1, - guid->Data2, guid->Data3, guid->Data4[0], guid->Data4[1], guid->Data4[2], - guid->Data4[3], guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]); -} - HRESULT WINAPI InitPropVariantFromGUIDAsString(REFGUID guid, PROPVARIANT *ppropvar) { TRACE("(%p %p)\n", guid, ppropvar); diff --git a/dlls/propsys/tests/propsys.c b/dlls/propsys/tests/propsys.c index 2231bb2e16c..ae46011e983 100644 --- a/dlls/propsys/tests/propsys.c +++ b/dlls/propsys/tests/propsys.c @@ -667,9 +667,7 @@ static void test_PropVariantToStringAlloc(void) prop.vt = VT_CLSID; prop.puuid = (CLSID *)&dummy_guid; hres = PropVariantToStringAlloc(&prop, &str); - todo_wine ok(hres == S_OK, "PropVariantToStringAlloc returned %#lx.\n", hres); - if (hres == S_OK) ok(!wcscmp(str, dummy_guid_str), "Unexpected str %s.\n", debugstr_w(str)); CoTaskMemFree(str); } @@ -1618,9 +1616,7 @@ static void test_PropVariantToString(void) propvar.vt = VT_CLSID; propvar.puuid = (CLSID *)&dummy_guid; hr = PropVariantToString(&propvar, bufferW, ARRAY_SIZE(bufferW)); - todo_wine ok(hr == S_OK, "PropVariantToString returned %#lx.\n", hr); - todo_wine ok(!wcscmp(bufferW, dummy_guid_str), "Unexpected string %s.\n", debugstr_w(bufferW)); memset(bufferW, 0, sizeof(bufferW)); }
From: Ziqing Hui zhui@codeweavers.com
--- dlls/propsys/propvar.c | 55 +++++++++++++++++++++++++++++++++++- dlls/propsys/tests/propsys.c | 8 ------ 2 files changed, 54 insertions(+), 9 deletions(-)
diff --git a/dlls/propsys/propvar.c b/dlls/propsys/propvar.c index c54fe868ee3..d70037a7ec5 100644 --- a/dlls/propsys/propvar.c +++ b/dlls/propsys/propvar.c @@ -1056,7 +1056,60 @@ INT WINAPI PropVariantCompareEx(REFPROPVARIANT propvar1, REFPROPVARIANT propvar2
HRESULT WINAPI PropVariantToVariant(const PROPVARIANT *propvar, VARIANT *var) { - return E_NOTIMPL; + HRESULT hr = S_OK; + + TRACE("propvar %p, var %p, propvar->vt %#x.\n", var, propvar, propvar->vt); + + if (!var || !propvar) + return E_INVALIDARG; + + VariantInit(var); + var->vt = propvar->vt; + + switch (propvar->vt) + { + case VT_EMPTY: + case VT_NULL: + break; + case VT_I1: + V_I1(var) = propvar->cVal; + break; + case VT_I2: + V_I2(var) = propvar->iVal; + break; + case VT_I4: + V_I4(var) = propvar->lVal; + break; + case VT_I8: + V_I8(var) = propvar->hVal.QuadPart; + break; + case VT_UI1: + V_UI1(var) = propvar->bVal; + break; + case VT_UI2: + V_UI2(var) = propvar->uiVal; + break; + case VT_UI4: + V_UI4(var) = propvar->ulVal; + break; + case VT_UI8: + V_UI8(var) = propvar->uhVal.QuadPart; + break; + case VT_BOOL: + V_BOOL(var) = propvar->boolVal; + break; + case VT_R4: + V_R4(var) = propvar->fltVal; + break; + case VT_R8: + V_R8(var) = propvar->dblVal; + break; + default: + FIXME("Unsupported type %d.\n", propvar->vt); + return E_INVALIDARG; + } + + return hr; }
HRESULT WINAPI VariantToPropVariant(const VARIANT *var, PROPVARIANT *propvar) diff --git a/dlls/propsys/tests/propsys.c b/dlls/propsys/tests/propsys.c index ae46011e983..5d8f549a44d 100644 --- a/dlls/propsys/tests/propsys.c +++ b/dlls/propsys/tests/propsys.c @@ -2439,10 +2439,8 @@ static void test_PropVariantToVariant(void) PropVariantInit(&propvar);
hr = PropVariantToVariant(NULL, &var); - todo_wine ok(hr == E_INVALIDARG, "PropVariantToVariant returned %#lx.\n", hr); hr = PropVariantToVariant(&propvar, NULL); - todo_wine ok(hr == E_INVALIDARG, "PropVariantToVariant returned %#lx.\n", hr);
propvar.vt = 0xdead; @@ -2456,19 +2454,14 @@ static void test_PropVariantToVariant(void)
propvar.vt = VT_EMPTY; hr = PropVariantToVariant(&propvar, &var); - todo_wine ok(hr == S_OK, "PropVariantToVariant returned %#lx.\n", hr); ok(V_VT(&var) == VT_EMPTY, "Unexpected V_VT(&var) %d.\n", V_VT(&var));
propvar.vt = VT_NULL; hr = PropVariantToVariant(&propvar, &var); - todo_wine ok(hr == S_OK, "PropVariantToVariant returned %#lx.\n", hr); - todo_wine ok(V_VT(&var) == VT_NULL, "Unexpected V_VT(&var) %d.\n", V_VT(&var));
- todo_wine - { check_PropVariantToVariant(propvar, var, I1, cVal, 'X', "%c"); check_PropVariantToVariant(propvar, var, I2, iVal, -456, "%d"); check_PropVariantToVariant(propvar, var, I4, lVal, -789, "%ld"); @@ -2483,7 +2476,6 @@ static void test_PropVariantToVariant(void)
check_PropVariantToVariant(propvar, var, R4, fltVal, 0.123f, "%f"); check_PropVariantToVariant(propvar, var, R8, dblVal, 0.456f, "%f"); - }
propvar.vt = VT_BSTR; propvar.bstrVal = SysAllocString(L"test");
@huw ready to be reviewed now.
Nikolay Sivov (@nsivov) commented about dlls/propsys/propvar.c:
HRESULT WINAPI PropVariantToVariant(const PROPVARIANT *propvar, VARIANT *var) {
- return E_NOTIMPL;
- HRESULT hr = S_OK;
- TRACE("propvar %p, var %p, propvar->vt %#x.\n", var, propvar, propvar->vt);
The order is wrong. Also, it shouldn't crash on null referencing when traces are enabled.
Nikolay Sivov (@nsivov) commented about dlls/propsys/propvar.c:
HRESULT WINAPI PropVariantToVariant(const PROPVARIANT *propvar, VARIANT *var) {
- return E_NOTIMPL;
- HRESULT hr = S_OK;
This could be removed, you're not using it.