This is based on top of !6526, will mark ready after !6526 is merged.
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 | 27 ++++++++++++++------------- dlls/propsys/tests/propsys.c | 4 ---- 2 files changed, 14 insertions(+), 17 deletions(-)
diff --git a/dlls/propsys/propvar.c b/dlls/propsys/propvar.c index 6500926380f..a63286d2c2b 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); @@ -356,7 +357,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 +421,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; + StringFromGUID2(propvarIn->puuid, res, GUID_STR_LEN + 1); + } + break; + default: FIXME("Unsupported conversion (%d)\n", propvarIn->vt); hr = E_FAIL; @@ -654,14 +663,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); @@ -670,11 +671,11 @@ HRESULT WINAPI InitPropVariantFromGUIDAsString(REFGUID guid, PROPVARIANT *ppropv return E_FAIL;
ppropvar->vt = VT_LPWSTR; - ppropvar->pwszVal = CoTaskMemAlloc(39*sizeof(WCHAR)); + ppropvar->pwszVal = CoTaskMemAlloc((GUID_STR_LEN + 1) * sizeof(WCHAR)); if(!ppropvar->pwszVal) return E_OUTOFMEMORY;
- PROPVAR_GUIDToWSTR(guid, ppropvar->pwszVal); + StringFromGUID2(guid, ppropvar->pwszVal, GUID_STR_LEN + 1); return S_OK; }
@@ -688,11 +689,11 @@ HRESULT WINAPI InitVariantFromGUIDAsString(REFGUID guid, VARIANT *pvar) }
V_VT(pvar) = VT_BSTR; - V_BSTR(pvar) = SysAllocStringLen(NULL, 38); + V_BSTR(pvar) = SysAllocStringLen(NULL, GUID_STR_LEN); if(!V_BSTR(pvar)) return E_OUTOFMEMORY;
- PROPVAR_GUIDToWSTR(guid, V_BSTR(pvar)); + StringFromGUID2(guid, V_BSTR(pvar), GUID_STR_LEN + 1); return S_OK; }
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 | 53 +++++++++++++++++++++++++++++++++++- dlls/propsys/tests/propsys.c | 8 ------ 2 files changed, 52 insertions(+), 9 deletions(-)
diff --git a/dlls/propsys/propvar.c b/dlls/propsys/propvar.c index a63286d2c2b..9bdb11f7de7 100644 --- a/dlls/propsys/propvar.c +++ b/dlls/propsys/propvar.c @@ -1049,7 +1049,58 @@ INT WINAPI PropVariantCompareEx(REFPROPVARIANT propvar1, REFPROPVARIANT propvar2
HRESULT WINAPI PropVariantToVariant(const PROPVARIANT *propvar, VARIANT *var) { - return E_NOTIMPL; + TRACE("propvar %p, var %p, propvar->vt %#x.\n", propvar, var, propvar ? propvar->vt : 0); + + 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 S_OK; }
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");
From: Ziqing Hui zhui@codeweavers.com
--- dlls/propsys/propsys.spec | 2 +- dlls/propsys/propvar.c | 7 +++++++ include/propvarutil.h | 1 + 3 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/dlls/propsys/propsys.spec b/dlls/propsys/propsys.spec index e6f2853b2a0..6a608ca88c1 100644 --- a/dlls/propsys/propsys.spec +++ b/dlls/propsys/propsys.spec @@ -106,7 +106,7 @@ @ stub PropVariantGetUInt16Elem @ stub PropVariantGetUInt32Elem @ stub PropVariantGetUInt64Elem -@ stub PropVariantToBSTR +@ stdcall PropVariantToBSTR(ptr ptr) @ stdcall PropVariantToBoolean(ptr ptr) @ stub PropVariantToBooleanVector @ stub PropVariantToBooleanVectorAlloc diff --git a/dlls/propsys/propvar.c b/dlls/propsys/propvar.c index 9bdb11f7de7..4a60f2c2c7e 100644 --- a/dlls/propsys/propvar.c +++ b/dlls/propsys/propvar.c @@ -332,6 +332,13 @@ HRESULT WINAPI PropVariantToBoolean(REFPROPVARIANT propvarIn, BOOL *ret) return hr; }
+HRESULT WINAPI PropVariantToBSTR(REFPROPVARIANT propvar, BSTR *bstr) +{ + FIXME("propvar %p, bstr %p.\n", propvar, bstr); + + return E_NOTIMPL; +} + HRESULT WINAPI PropVariantToBuffer(REFPROPVARIANT propvarIn, void *ret, UINT cb) { HRESULT hr = S_OK; diff --git a/include/propvarutil.h b/include/propvarutil.h index 29c0bf7796b..0c23c7caa70 100644 --- a/include/propvarutil.h +++ b/include/propvarutil.h @@ -102,6 +102,7 @@ PSSTDAPI PropVariantToUInt32(REFPROPVARIANT propvarIn, ULONG *ret); PSSTDAPI_(ULONG) PropVariantToUInt32WithDefault(REFPROPVARIANT propvarIn, ULONG uLDefault); PSSTDAPI PropVariantToUInt64(REFPROPVARIANT propvarIn, ULONGLONG *ret); PSSTDAPI PropVariantToBoolean(REFPROPVARIANT propvarIn, BOOL *ret); +PSSTDAPI PropVariantToBSTR(REFPROPVARIANT propvar, BSTR *bstr); PSSTDAPI PropVariantToBuffer(REFPROPVARIANT propvarIn, void *ret, UINT cb); PSSTDAPI PropVariantToString(REFPROPVARIANT propvarIn, PWSTR ret, UINT cch); PSSTDAPI_(PCWSTR) PropVariantToStringWithDefault(REFPROPVARIANT propvarIn, LPCWSTR pszDefault);
From: Ziqing Hui zhui@codeweavers.com
--- dlls/propsys/tests/propsys.c | 94 +++++++++++++++++++++++++++++++++++- 1 file changed, 93 insertions(+), 1 deletion(-)
diff --git a/dlls/propsys/tests/propsys.c b/dlls/propsys/tests/propsys.c index 5d8f549a44d..c1b6ee179a0 100644 --- a/dlls/propsys/tests/propsys.c +++ b/dlls/propsys/tests/propsys.c @@ -1621,6 +1621,98 @@ static void test_PropVariantToString(void) memset(bufferW, 0, sizeof(bufferW)); }
+#define check_PropVariantToBSTR(type, member, value, expect_str) \ +do \ +{ \ + PROPVARIANT check_propvar_ = {.vt = (type), .member = (value)}; \ + HRESULT check_hr_; \ + WCHAR *check_bsr_; \ + \ + check_hr_ = PropVariantToBSTR(&check_propvar_, &check_bsr_); \ + ok_(__FILE__, __LINE__)(check_hr_ == S_OK, \ + "PropVariantToBSTR returned %#lx.\n", check_hr_); \ + \ + if (check_hr_ == S_OK) \ + { \ + ok_(__FILE__, __LINE__)(!wcscmp(check_bsr_, (expect_str)), \ + "Unexpected bstr %s.\n", debugstr_w(check_bsr_)); \ + SysFreeString(check_bsr_); \ + } \ +} while (0) + +static void test_PropVariantToBSTR(void) +{ + WCHAR *bstr, *test_bstr = SysAllocString(topicW); + unsigned char test_bytes[] = {1, 20, 30, 4}; + PROPVARIANT propvar; + HRESULT hr; + + if (0) /* Crashes. */ + { + hr = PropVariantToBSTR(&propvar, NULL); + hr = PropVariantToBSTR(NULL, &bstr); + } + + todo_wine + { + check_PropVariantToBSTR(VT_I1, cVal, -123, L"-123"); + check_PropVariantToBSTR(VT_I2, iVal, -456, L"-456"); + check_PropVariantToBSTR(VT_I4, lVal, -789, L"-789"); + check_PropVariantToBSTR(VT_I8, hVal.QuadPart, -101112, L"-101112"); + check_PropVariantToBSTR(VT_UI1, bVal, 0xcd, L"205"); + check_PropVariantToBSTR(VT_UI2, uiVal, 0xdead, L"57005"); + check_PropVariantToBSTR(VT_UI4, ulVal, 0xdeadbeef, L"3735928559"); + check_PropVariantToBSTR(VT_UI8, uhVal.QuadPart, 0xdeadbeefdeadbeef, L"16045690984833335023"); + check_PropVariantToBSTR(VT_BOOL, boolVal, TRUE, L"1"); + check_PropVariantToBSTR(VT_R4, fltVal, 0.123f, L"0.123000003397464752"); + check_PropVariantToBSTR(VT_R8, dblVal, 0.456f, L"0.456000000238418579"); + check_PropVariantToBSTR(VT_CLSID, puuid, (CLSID *)&dummy_guid, dummy_guid_str); + check_PropVariantToBSTR(VT_LPSTR, pszVal, (char *)topic, topicW); + check_PropVariantToBSTR(VT_LPWSTR, pwszVal, (WCHAR *)topicW, topicW); + check_PropVariantToBSTR(VT_BSTR, bstrVal, test_bstr, topicW); + } + + PropVariantInit(&propvar); + propvar.vt = VT_FILETIME; + propvar.filetime.dwLowDateTime = 0xdead; + propvar.filetime.dwHighDateTime = 0xbeef; + hr = PropVariantToBSTR(&propvar, &bstr); + todo_wine + ok(hr == S_OK, "PropVariantToBSTR returned %#lx.\n", hr); + if (hr == S_OK) + { + ok(!wcscmp(bstr, L"1601/08/31:23:29:30.651"), "Unexpected bstr %s.\n", debugstr_w(bstr)); + SysFreeString(bstr); + } + + PropVariantInit(&propvar); + propvar.vt = VT_DATE; + propvar.date = 123.123f; + hr = PropVariantToBSTR(&propvar, &bstr); + todo_wine + ok(hr == S_OK, "PropVariantToBSTR returned %#lx.\n", hr); + if (hr == S_OK) + { + ok(!wcscmp(bstr, L"1900/05/02:02:57:07.000"), "Unexpected bstr %s.\n", debugstr_w(bstr)); + SysFreeString(bstr); + } + + PropVariantInit(&propvar); + propvar.vt = VT_VECTOR | VT_I1; + propvar.caub.cElems = ARRAY_SIZE(test_bytes); + propvar.caub.pElems = test_bytes; + hr = PropVariantToBSTR(&propvar, &bstr); + todo_wine + ok(hr == S_OK, "PropVariantToBSTR returned %#lx.\n", hr); + if (hr == S_OK) + { + ok(!wcscmp(bstr, L"1; 20; 30; 4"), "Unexpected bstr %s.\n", debugstr_w(bstr)); + SysFreeString(bstr); + } + + SysFreeString(bstr); +} + static void test_PropVariantToBuffer(void) { PROPVARIANT propvar; @@ -2365,7 +2457,6 @@ static void test_VariantToString(void) "Unexpected V_"#type"(&var) "format".\n", (propvar).member); \ } while (0)
- static void test_VariantToPropVariant(void) { PROPVARIANT propvar; @@ -2549,6 +2640,7 @@ START_TEST(propsys) test_PropVariantToStringWithDefault(); test_PropVariantToDouble(); test_PropVariantToString(); + test_PropVariantToBSTR(); test_PropVariantToBuffer(); test_inmemorystore(); test_persistserialized();
From: Ziqing Hui zhui@codeweavers.com
--- dlls/propsys/tests/propsys.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-)
diff --git a/dlls/propsys/tests/propsys.c b/dlls/propsys/tests/propsys.c index c1b6ee179a0..a0d7eee4f85 100644 --- a/dlls/propsys/tests/propsys.c +++ b/dlls/propsys/tests/propsys.c @@ -1526,10 +1526,10 @@ static void test_PropVariantToDouble(void)
static void test_PropVariantToString(void) { - PROPVARIANT propvar; + static WCHAR stringW[] = L"Wine", stringW_truncated[] = L"Win"; static CHAR string[] = "Wine"; - static WCHAR stringW[] = {'W','i','n','e',0}; WCHAR bufferW[256] = {0}; + PROPVARIANT propvar; HRESULT hr;
PropVariantInit(&propvar); @@ -1587,12 +1587,23 @@ static void test_PropVariantToString(void) ok(!lstrcmpW(bufferW, stringW), "got wrong string: "%s".\n", wine_dbgstr_w(bufferW)); memset(bufferW, 0, sizeof(bufferW));
+ /* Result string will be truncated if output buffer is too small. */ + PropVariantInit(&propvar); + propvar.vt = VT_UI4; + propvar.lVal = 123456; + hr = PropVariantToString(&propvar, bufferW, 4); + todo_wine + ok(hr == STRSAFE_E_INSUFFICIENT_BUFFER, "PropVariantToString returned: %#lx.\n", hr); + todo_wine + ok(!wcscmp(bufferW, L"123"), "Unexpected string %s.\n", debugstr_w(bufferW)); + memset(bufferW, 0, sizeof(bufferW)); + PropVariantInit(&propvar); propvar.vt = VT_LPWSTR; propvar.pwszVal = stringW; hr = PropVariantToString(&propvar, bufferW, 4); ok(hr == STRSAFE_E_INSUFFICIENT_BUFFER, "PropVariantToString returned: 0x%08lx.\n", hr); - ok(!memcmp(bufferW, stringW, 4), "got wrong string.\n"); + ok(!wcscmp(bufferW, stringW_truncated), "Unexpected string %s.\n", debugstr_w(bufferW)); memset(bufferW, 0, sizeof(bufferW));
PropVariantInit(&propvar); @@ -1600,7 +1611,7 @@ static void test_PropVariantToString(void) propvar.pszVal = string; hr = PropVariantToString(&propvar, bufferW, 4); ok(hr == STRSAFE_E_INSUFFICIENT_BUFFER, "PropVariantToString returned: 0x%08lx.\n", hr); - ok(!memcmp(bufferW, stringW, 4), "got wrong string.\n"); + ok(!wcscmp(bufferW, stringW_truncated), "Unexpected string %s.\n", debugstr_w(bufferW)); memset(bufferW, 0, sizeof(bufferW));
PropVariantInit(&propvar);
From: Ziqing Hui zhui@codeweavers.com
--- dlls/propsys/propsys_main.c | 2 +- dlls/propsys/propvar.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/dlls/propsys/propsys_main.c b/dlls/propsys/propsys_main.c index 6e87b3d3579..2270e8423e8 100644 --- a/dlls/propsys/propsys_main.c +++ b/dlls/propsys/propsys_main.c @@ -279,7 +279,7 @@ HRESULT WINAPI PSStringFromPropertyKey(REFPROPERTYKEY pkey, LPWSTR psz, UINT cch
if (cch >= len + 1) { - lstrcpyW(p, pidW); + wcscpy(p, pidW); return S_OK; } else diff --git a/dlls/propsys/propvar.c b/dlls/propsys/propvar.c index 4a60f2c2c7e..e9d2e7f5f20 100644 --- a/dlls/propsys/propvar.c +++ b/dlls/propsys/propvar.c @@ -296,13 +296,13 @@ HRESULT WINAPI PropVariantToBoolean(REFPROPVARIANT propvarIn, BOOL *ret) if (!propvarIn->pwszVal) return DISP_E_TYPEMISMATCH;
- if (!lstrcmpiW(propvarIn->pwszVal, L"true") || !lstrcmpW(propvarIn->pwszVal, L"#TRUE#")) + if (!wcsicmp(propvarIn->pwszVal, L"true") || !wcscmp(propvarIn->pwszVal, L"#TRUE#")) { *ret = TRUE; return S_OK; }
- if (!lstrcmpiW(propvarIn->pwszVal, L"false") || !lstrcmpW(propvarIn->pwszVal, L"#FALSE#")) + if (!wcsicmp(propvarIn->pwszVal, L"false") || !wcscmp(propvarIn->pwszVal, L"#FALSE#")) { *ret = FALSE; return S_OK; @@ -1020,9 +1020,9 @@ INT WINAPI PropVariantCompareEx(REFPROPVARIANT propvar1, REFPROPVARIANT propvar2 case VT_LPWSTR: /* FIXME: Use other string flags. */ if (flags & (PVCF_USESTRCMPI | PVCF_USESTRCMPIC)) - res = lstrcmpiW(propvar1->bstrVal, propvar2_converted->bstrVal); + res = wcsicmp(propvar1->bstrVal, propvar2_converted->bstrVal); else - res = lstrcmpW(propvar1->bstrVal, propvar2_converted->bstrVal); + res = wcscmp(propvar1->bstrVal, propvar2_converted->bstrVal); break; case VT_LPSTR: /* FIXME: Use other string flags. */
From: Ziqing Hui zhui@codeweavers.com
--- dlls/propsys/propvar.c | 14 ++++++++++++-- dlls/propsys/tests/propsys.c | 2 +- 2 files changed, 13 insertions(+), 3 deletions(-)
diff --git a/dlls/propsys/propvar.c b/dlls/propsys/propvar.c index e9d2e7f5f20..ddb60aa0d97 100644 --- a/dlls/propsys/propvar.c +++ b/dlls/propsys/propvar.c @@ -334,9 +334,19 @@ HRESULT WINAPI PropVariantToBoolean(REFPROPVARIANT propvarIn, BOOL *ret)
HRESULT WINAPI PropVariantToBSTR(REFPROPVARIANT propvar, BSTR *bstr) { - FIXME("propvar %p, bstr %p.\n", propvar, bstr); + WCHAR *str; + HRESULT hr; + + TRACE("propvar %p, propvar->vt %#x, bstr %p.\n", + propvar, propvar ? propvar->vt : 0, bstr); + + if (FAILED(hr = PropVariantToStringAlloc(propvar, &str))) + return hr; + + *bstr = SysAllocString(str); + CoTaskMemFree(str);
- return E_NOTIMPL; + return S_OK; }
HRESULT WINAPI PropVariantToBuffer(REFPROPVARIANT propvarIn, void *ret, UINT cb) diff --git a/dlls/propsys/tests/propsys.c b/dlls/propsys/tests/propsys.c index a0d7eee4f85..43e02b53a4a 100644 --- a/dlls/propsys/tests/propsys.c +++ b/dlls/propsys/tests/propsys.c @@ -1677,11 +1677,11 @@ static void test_PropVariantToBSTR(void) check_PropVariantToBSTR(VT_BOOL, boolVal, TRUE, L"1"); check_PropVariantToBSTR(VT_R4, fltVal, 0.123f, L"0.123000003397464752"); check_PropVariantToBSTR(VT_R8, dblVal, 0.456f, L"0.456000000238418579"); + } check_PropVariantToBSTR(VT_CLSID, puuid, (CLSID *)&dummy_guid, dummy_guid_str); check_PropVariantToBSTR(VT_LPSTR, pszVal, (char *)topic, topicW); check_PropVariantToBSTR(VT_LPWSTR, pwszVal, (WCHAR *)topicW, topicW); check_PropVariantToBSTR(VT_BSTR, bstrVal, test_bstr, topicW); - }
PropVariantInit(&propvar); propvar.vt = VT_FILETIME;
From: Ziqing Hui zhui@codeweavers.com
--- dlls/propsys/propvar.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/dlls/propsys/propvar.c b/dlls/propsys/propvar.c index ddb60aa0d97..951788ca259 100644 --- a/dlls/propsys/propvar.c +++ b/dlls/propsys/propvar.c @@ -1124,7 +1124,8 @@ HRESULT WINAPI VariantToPropVariant(const VARIANT *var, PROPVARIANT *propvar) { HRESULT hr;
- TRACE("var %p, propvar %p, var->vt %04x.\n", var, propvar, var->vt); + TRACE("var %p, var->vt %#x, propvar %p.\n", + var, var ? var->vt : 0, propvar);
if (!var || !propvar) return E_INVALIDARG;
From: Ziqing Hui zhui@codeweavers.com
--- dlls/propsys/propvar.c | 14 ++++++++++++-- dlls/propsys/tests/propsys.c | 15 --------------- 2 files changed, 12 insertions(+), 17 deletions(-)
diff --git a/dlls/propsys/propvar.c b/dlls/propsys/propvar.c index 951788ca259..6d6c25f96b1 100644 --- a/dlls/propsys/propvar.c +++ b/dlls/propsys/propvar.c @@ -1066,6 +1066,8 @@ INT WINAPI PropVariantCompareEx(REFPROPVARIANT propvar1, REFPROPVARIANT propvar2
HRESULT WINAPI PropVariantToVariant(const PROPVARIANT *propvar, VARIANT *var) { + HRESULT hr = S_OK; + TRACE("propvar %p, var %p, propvar->vt %#x.\n", propvar, var, propvar ? propvar->vt : 0);
if (!var || !propvar) @@ -1112,12 +1114,20 @@ HRESULT WINAPI PropVariantToVariant(const PROPVARIANT *propvar, VARIANT *var) case VT_R8: V_R8(var) = propvar->dblVal; break; + case VT_LPSTR: + case VT_LPWSTR: + case VT_BSTR: + case VT_CLSID: + var->vt = VT_BSTR; + hr = PropVariantToBSTR(propvar, &V_BSTR(var)); + break; default: FIXME("Unsupported type %d.\n", propvar->vt); - return E_INVALIDARG; + hr = E_INVALIDARG; + break; }
- return S_OK; + 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 43e02b53a4a..689d8be4ea5 100644 --- a/dlls/propsys/tests/propsys.c +++ b/dlls/propsys/tests/propsys.c @@ -2582,14 +2582,10 @@ static void test_PropVariantToVariant(void) 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);
@@ -2598,36 +2594,25 @@ static void test_PropVariantToVariant(void) 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); }
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=148939
Your paranoid android.
=== w7u_2qxl (32 bit report) ===
propsys: propsys.c:1678: Test failed: Unexpected bstr L"5.1378823111276E-315". propsys.c:1679: Test failed: Unexpected bstr L"0.45600000023841858".
=== w7u_adm (32 bit report) ===
propsys: propsys.c:1678: Test failed: Unexpected bstr L"5.1378823111276E-315". propsys.c:1679: Test failed: Unexpected bstr L"0.45600000023841858".
=== w7u_el (32 bit report) ===
propsys: propsys.c:1678: Test failed: Unexpected bstr L"5.1378823111276E-315". propsys.c:1679: Test failed: Unexpected bstr L"0.45600000023841858".
=== w8 (32 bit report) ===
propsys: propsys.c:1678: Test failed: Unexpected bstr L"0.12300000339746475". propsys.c:1679: Test failed: Unexpected bstr L"0.45600000023841858".
=== w8adm (32 bit report) ===
propsys: propsys.c:1678: Test failed: Unexpected bstr L"0.12300000339746475". propsys.c:1679: Test failed: Unexpected bstr L"0.45600000023841858".
=== w864 (32 bit report) ===
propsys: propsys.c:1678: Test failed: Unexpected bstr L"0.12300000339746475". propsys.c:1679: Test failed: Unexpected bstr L"0.45600000023841858".
=== w1064v1507 (32 bit report) ===
propsys: propsys.c:1678: Test failed: Unexpected bstr L"0.12300000339746475". propsys.c:1679: Test failed: Unexpected bstr L"0.45600000023841858".
=== w1064v1809 (32 bit report) ===
propsys: propsys.c:1678: Test failed: Unexpected bstr L"0.12300000339746475". propsys.c:1679: Test failed: Unexpected bstr L"0.45600000023841858".
=== w7pro64 (64 bit report) ===
propsys: propsys.c:1678: Test failed: Unexpected bstr L"5.1378823111276E-315". propsys.c:1679: Test failed: Unexpected bstr L"0.45600000023841858".
=== w864 (64 bit report) ===
propsys: propsys.c:1678: Test failed: Unexpected bstr L"0.12300000339746475". propsys.c:1679: Test failed: Unexpected bstr L"0.45600000023841858".
=== w1064v1507 (64 bit report) ===
propsys: propsys.c:1678: Test failed: Unexpected bstr L"0.12300000339746475". propsys.c:1679: Test failed: Unexpected bstr L"0.45600000023841858".
=== w1064v1809 (64 bit report) ===
propsys: propsys.c:1678: Test failed: Unexpected bstr L"0.12300000339746475". propsys.c:1679: Test failed: Unexpected bstr L"0.45600000023841858".