Signed-off-by: Mohamad Al-Jaf mohamadaljaf@gmail.com --- v2: - Support byref BSTR. - Support nested VARIANT including byref BSTR.
v3: - Consolidate code.
v4: - Retrieve string as BSTR.
v5: - Remove unnecessary variable. --- dlls/propsys/propsys.spec | 2 +- dlls/propsys/propvar.c | 20 ++++++++++++++++++++ include/propvarutil.h | 6 ++++++ 3 files changed, 27 insertions(+), 1 deletion(-)
diff --git a/dlls/propsys/propsys.spec b/dlls/propsys/propsys.spec index 15749952e95..7391cf4aaa2 100644 --- a/dlls/propsys/propsys.spec +++ b/dlls/propsys/propsys.spec @@ -194,7 +194,7 @@ @ stub VariantToStringAlloc @ stub VariantToStringArray @ stub VariantToStringArrayAlloc -@ stub VariantToStringWithDefault +@ stdcall VariantToStringWithDefault(ptr wstr) @ stub VariantToUInt16 @ stub VariantToUInt16Array @ stub VariantToUInt16ArrayAlloc diff --git a/dlls/propsys/propvar.c b/dlls/propsys/propvar.c index 8f6c52f7aa7..61b1b4313ef 100644 --- a/dlls/propsys/propvar.c +++ b/dlls/propsys/propvar.c @@ -416,6 +416,26 @@ PCWSTR WINAPI PropVariantToStringWithDefault(REFPROPVARIANT propvarIn, LPCWSTR p return pszDefault; }
+/****************************************************************** + * VariantToStringWithDefault (PROPSYS.@) + */ +PCWSTR WINAPI VariantToStringWithDefault(const VARIANT *pvar, LPCWSTR pszDefault) +{ + TRACE("(%p, %s)\n", pvar, debugstr_w(pszDefault)); + + if (V_VT(pvar) == (VT_BYREF | VT_VARIANT)) pvar = V_VARIANTREF(pvar); + if (V_VT(pvar) == (VT_BYREF | VT_BSTR) || V_VT(pvar) == VT_BSTR) + { + BSTR ret; + ret = V_ISBYREF(pvar) ? *V_BSTRREF(pvar) : V_BSTR(pvar); + + if (!ret) return L""; + return ret; + } + + return pszDefault; +} +
/****************************************************************** * PropVariantChangeType (PROPSYS.@) diff --git a/include/propvarutil.h b/include/propvarutil.h index 36a670f56e6..2515d71b3b6 100644 --- a/include/propvarutil.h +++ b/include/propvarutil.h @@ -93,6 +93,7 @@ HRESULT WINAPI PropVariantToBoolean(REFPROPVARIANT propvarIn, BOOL *ret); HRESULT WINAPI PropVariantToBuffer(REFPROPVARIANT propvarIn, void *ret, UINT cb); HRESULT WINAPI PropVariantToString(REFPROPVARIANT propvarIn, PWSTR ret, UINT cch); PCWSTR WINAPI PropVariantToStringWithDefault(REFPROPVARIANT propvarIn, LPCWSTR pszDefault); +PCWSTR WINAPI VariantToStringWithDefault(const VARIANT *pvar, LPCWSTR pszDefault);
HRESULT WINAPI PropVariantToStringAlloc(REFPROPVARIANT propvarIn, WCHAR **ret);
@@ -201,6 +202,11 @@ inline BOOL IsPropVariantString(REFPROPVARIANT propvar) return (PropVariantToStringWithDefault(propvar, NULL) != NULL); }
+inline BOOL IsVariantString(const VARIANT *pvar) +{ + return (VariantToStringWithDefault(pvar, NULL) != NULL); +} + #endif /* NO_PROPVAR_INLINES */ #endif /* __cplusplus */
Signed-off-by: Mohamad Al-Jaf mohamadaljaf@gmail.com --- v2: - Add some more tests to see what variants are supported. - Test for BYREF. - Test nested BSTR and BYREF.
v3: - Add test for NULL default_value (Thanks Nikolay). - Test returned pointer value with BSTR.
v4: - Add some more tests for NULL default_value. --- dlls/propsys/tests/propsys.c | 197 +++++++++++++++++++++++++++++++++++ 1 file changed, 197 insertions(+)
diff --git a/dlls/propsys/tests/propsys.c b/dlls/propsys/tests/propsys.c index 124b3405bcb..27d80d41ae9 100644 --- a/dlls/propsys/tests/propsys.c +++ b/dlls/propsys/tests/propsys.c @@ -2064,6 +2064,202 @@ static void test_InitVariantFromFileTime(void) ok(V_DATE(&var) == d, "got wrong value: %f, expected %f\n", V_DATE(&var), d); }
+static void test_VariantToStringWithDefault(void) +{ + static WCHAR default_value[] = {'t', 'e', 's', 't', '\0'}; + static WCHAR wstr_test[] = {'t', 'e', 's', 't', '1', '\0'}; + static WCHAR wstr_empty[] = {'\0'}; + static WCHAR wstr_space[] = {' ', '\0'}; + PCWSTR result; + VARIANT var, nes; + BSTR b; + + V_VT(&var) = VT_EMPTY; + result = VariantToStringWithDefault(&var, NULL); + ok(result == NULL, "Unexpected value %s\n", wine_dbgstr_w(result)); + result = VariantToStringWithDefault(&var, default_value); + ok(result == default_value, "Unexpected value %s\n", wine_dbgstr_w(result)); + + V_VT(&var) = VT_NULL; + result = VariantToStringWithDefault(&var, NULL); + ok(result == NULL, "Unexpected value %s\n", wine_dbgstr_w(result)); + result = VariantToStringWithDefault(&var, default_value); + ok(result == default_value, "Unexpected value %s\n", wine_dbgstr_w(result)); + + V_VT(&var) = VT_BOOL; + result = VariantToStringWithDefault(&var, NULL); + ok(result == NULL, "Unexpected value %s\n", wine_dbgstr_w(result)); + V_BOOL(&var) = VARIANT_TRUE; + result = VariantToStringWithDefault(&var, default_value); + ok(result == default_value, "Unexpected value %s\n", wine_dbgstr_w(result)); + + V_VT(&var) = VT_CY; + V_CY(&var).int64 = 100000; + result = VariantToStringWithDefault(&var, NULL); + ok(result == NULL, "Unexpected value %s\n", wine_dbgstr_w(result)); + result = VariantToStringWithDefault(&var, default_value); + ok(result == default_value, "Unexpected value %s\n", wine_dbgstr_w(result)); + + V_VT(&var) = VT_DATE; + V_DATE(&var) = 42.0; + result = VariantToStringWithDefault(&var, NULL); + ok(result == NULL, "Unexpected value %s\n", wine_dbgstr_w(result)); + result = VariantToStringWithDefault(&var, default_value); + ok(result == default_value, "Unexpected value %s\n", wine_dbgstr_w(result)); + + V_VT(&var) = VT_BYREF; + V_BYREF(&var) = &wstr_test; + result = VariantToStringWithDefault(&var, NULL); + ok(result == NULL, "Unexpected value %s\n", wine_dbgstr_w(result)); + result = VariantToStringWithDefault(&var, default_value); + ok(result == default_value, "Unexpected value %s\n", wine_dbgstr_w(result)); + + V_VT(&var) = VT_ERROR; + V_ERROR(&var) = DISP_E_PARAMNOTFOUND; + result = VariantToStringWithDefault(&var, NULL); + ok(result == NULL, "Unexpected value %s\n", wine_dbgstr_w(result)); + result = VariantToStringWithDefault(&var, default_value); + ok(result == default_value, "Unexpected value %s\n", wine_dbgstr_w(result)); + + V_VT(&var) = VT_I4; + V_I4(&var) = 15; + result = VariantToStringWithDefault(&var, NULL); + ok(result == NULL, "Unexpected value %s\n", wine_dbgstr_w(result)); + result = VariantToStringWithDefault(&var, default_value); + ok(result == default_value, "Unexpected value %s\n", wine_dbgstr_w(result)); + + V_VT(&var) = VT_I1; + V_I1(&var) = 't'; + result = VariantToStringWithDefault(&var, NULL); + ok(result == NULL, "Unexpected value %s\n", wine_dbgstr_w(result)); + result = VariantToStringWithDefault(&var, default_value); + ok(result == default_value, "Unexpected value %s\n", wine_dbgstr_w(result)); + + /* V_BSTR */ + + V_VT(&var) = VT_BSTR; + V_BSTR(&var) = NULL; + result = VariantToStringWithDefault(&var, default_value); + ok(result[0] == '\0', "Unexpected value %s\n", wine_dbgstr_w(result)); + + V_VT(&var) = VT_BSTR; + V_BSTR(&var) = SysAllocString(wstr_empty); + result = VariantToStringWithDefault(&var, default_value); + ok(result == V_BSTR(&var), "Unexpected value %s\n", wine_dbgstr_w(result)); + SysFreeString(V_BSTR(&var)); + + V_VT(&var) = VT_BSTR; + V_BSTR(&var) = SysAllocString(wstr_space); + result = VariantToStringWithDefault(&var, default_value); + ok(result == V_BSTR(&var), "Unexpected value %s\n", wine_dbgstr_w(result)); + SysFreeString(V_BSTR(&var)); + + V_VT(&var) = VT_BSTR; + V_BSTR(&var) = SysAllocString(wstr_test); + result = VariantToStringWithDefault(&var, default_value); + ok(result == V_BSTR(&var), "Unexpected value %s\n", wine_dbgstr_w(result)); + SysFreeString(V_BSTR(&var)); + + /* V_BSTRREF */ + + V_VT(&var) = VT_BYREF | VT_BSTR; + b = NULL; + V_BSTRREF(&var) = &b; + result = VariantToStringWithDefault(&var, default_value); + ok(result[0] == '\0', "Unexpected value %s\n", wine_dbgstr_w(result)); + + V_VT(&var) = VT_BYREF | VT_BSTR; + b = SysAllocString(wstr_empty); + V_BSTRREF(&var) = &b; + result = VariantToStringWithDefault(&var, default_value); + ok(result == b, "Unexpected value %s\n", wine_dbgstr_w(result)); + SysFreeString(b); + + V_VT(&var) = VT_BYREF | VT_BSTR; + b = SysAllocString(wstr_space); + V_BSTRREF(&var) = &b; + result = VariantToStringWithDefault(&var, default_value); + ok(result == b, "Unexpected value %s\n", wine_dbgstr_w(result)); + SysFreeString(b); + + V_VT(&var) = VT_BYREF | VT_BSTR; + b = SysAllocString(wstr_test); + V_BSTRREF(&var) = &b; + result = VariantToStringWithDefault(&var, default_value); + ok(result == b, "Unexpected value %s\n", wine_dbgstr_w(result)); + SysFreeString(b); + + /* Nested V_BSTR */ + + V_VT(&var) = VT_BYREF | VT_VARIANT; + V_VT(&nes) = VT_BSTR; + V_BSTR(&nes) = NULL; + V_VARIANTREF(&var) = &nes; + result = VariantToStringWithDefault(&var, default_value); + ok(result[0] == '\0', "Unexpected value %s\n", wine_dbgstr_w(result)); + + V_VT(&var) = VT_BYREF | VT_VARIANT; + V_VT(&nes) = VT_BSTR; + V_BSTR(&nes) = SysAllocString(wstr_empty); + V_VARIANTREF(&var) = &nes; + result = VariantToStringWithDefault(&var, default_value); + ok(result == V_BSTR(&nes), "Unexpected value %s\n", wine_dbgstr_w(result)); + SysFreeString(V_BSTR(&nes)); + + V_VT(&var) = VT_BYREF | VT_VARIANT; + V_VT(&nes) = VT_BSTR; + V_BSTR(&nes) = SysAllocString(wstr_space); + V_VARIANTREF(&var) = &nes; + result = VariantToStringWithDefault(&var, default_value); + ok(result == V_BSTR(&nes), "Unexpected value %s\n", wine_dbgstr_w(result)); + SysFreeString(V_BSTR(&nes)); + + V_VT(&var) = VT_BYREF | VT_VARIANT; + V_VT(&nes) = VT_BSTR; + V_BSTR(&nes) = SysAllocString(wstr_test); + V_VARIANTREF(&var) = &nes; + result = VariantToStringWithDefault(&var, default_value); + ok(result == V_BSTR(&nes), "Unexpected value %s\n", wine_dbgstr_w(result)); + SysFreeString(V_BSTR(&nes)); + + /* Nested V_BSTRREF */ + + V_VT(&var) = VT_BYREF | VT_VARIANT; + V_VT(&nes) = VT_BYREF | VT_BSTR; + b = NULL; + V_BSTRREF(&nes) = &b; + V_VARIANTREF(&var) = &nes; + result = VariantToStringWithDefault(&var, default_value); + ok(result[0] == '\0', "Unexpected value %s\n", wine_dbgstr_w(result)); + + V_VT(&var) = VT_BYREF | VT_VARIANT; + V_VT(&nes) = VT_BYREF | VT_BSTR; + b = SysAllocString(wstr_empty); + V_BSTRREF(&nes) = &b; + V_VARIANTREF(&var) = &nes; + result = VariantToStringWithDefault(&var, default_value); + ok(result == b, "Unexpected value %s\n", wine_dbgstr_w(result)); + SysFreeString(b); + + V_VT(&var) = VT_BYREF | VT_VARIANT; + V_VT(&nes) = VT_BYREF | VT_BSTR; + b = SysAllocString(wstr_space); + V_BSTRREF(&nes) = &b; + V_VARIANTREF(&var) = &nes; + result = VariantToStringWithDefault(&var, default_value); + ok(result == b, "Unexpected value %s\n", wine_dbgstr_w(result)); + SysFreeString(b); + + V_VT(&var) = VT_BYREF | VT_VARIANT; + V_VT(&nes) = VT_BYREF | VT_BSTR; + b = SysAllocString(wstr_test); + V_BSTRREF(&nes) = &b; + V_VARIANTREF(&var) = &nes; + result = VariantToStringWithDefault(&var, default_value); + ok(result == b, "Unexpected value %s\n", wine_dbgstr_w(result)); + SysFreeString(b); +} + START_TEST(propsys) { test_PSStringFromPropertyKey(); @@ -2088,4 +2284,5 @@ START_TEST(propsys) test_propertystore(); test_PSCreatePropertyStoreFromObject(); test_InitVariantFromFileTime(); + test_VariantToStringWithDefault(); }