IE8 runtime calls upon this function and crashes without it.
Signed-off-by: Mohamad Al-Jaf mohamadaljaf@gmail.com --- Kept the same naming convention as the other functions for consistency. --- dlls/propsys/propsys.spec | 2 +- dlls/propsys/propvar.c | 17 +++++++++++++++++ include/propvarutil.h | 6 ++++++ 3 files changed, 24 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..18953cf381e 100644 --- a/dlls/propsys/propvar.c +++ b/dlls/propsys/propvar.c @@ -416,6 +416,23 @@ 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_BSTR) + { + if (V_BSTR(pvar) == NULL) + return L""; + + return V_BSTR(pvar); + } + + return pszDefault; +}
/****************************************************************** * PropVariantChangeType (PROPSYS.@) diff --git a/include/propvarutil.h b/include/propvarutil.h index 36a670f56e6..c8c9bae31e0 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 *var) +{ + return (VariantToStringWithDefault(var, NULL) != NULL); +} + #endif /* NO_PROPVAR_INLINES */ #endif /* __cplusplus */
Signed-off-by: Mohamad Al-Jaf mohamadaljaf@gmail.com --- dlls/propsys/tests/propsys.c | 54 ++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+)
diff --git a/dlls/propsys/tests/propsys.c b/dlls/propsys/tests/propsys.c index 124b3405bcb..0ba812da892 100644 --- a/dlls/propsys/tests/propsys.c +++ b/dlls/propsys/tests/propsys.c @@ -2064,6 +2064,59 @@ 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_test2[] = {'t', 'e', 's', 't', '2', 0}; + static WCHAR wstr_empty[] = {0}; + static WCHAR wstr_space[] = {' ', 0}; + LPCWSTR result; + VARIANT var; + + V_VT(&var) = VT_EMPTY; + 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, default_value); + ok(result == default_value, "Unexpected value %s\n", wine_dbgstr_w(result)); + + V_VT(&var) = VT_BOOL; + 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_I4; + V_I4(&var) = 15; + result = VariantToStringWithDefault(&var, default_value); + ok(result == default_value, "Unexpected value %s\n", wine_dbgstr_w(result)); + + /* VT_BSTR */ + + V_VT(&var) = VT_BSTR; + V_BSTR(&var) = NULL; + result = VariantToStringWithDefault(&var, default_value); + ok(!lstrcmpW(result, wstr_empty), "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(!lstrcmpW(result, wstr_empty), "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(!lstrcmpW(result, wstr_space), "Unexpected value %s\n", wine_dbgstr_w(result)); + SysFreeString(V_BSTR(&var)); + + V_VT(&var) = VT_BSTR; + V_BSTR(&var) = SysAllocString(wstr_test2); + result = VariantToStringWithDefault(&var, default_value); + ok(!lstrcmpW(result, wstr_test2), "Unexpected value %s\n", wine_dbgstr_w(result)); + SysFreeString(V_BSTR(&var)); +} + START_TEST(propsys) { test_PSStringFromPropertyKey(); @@ -2088,4 +2141,5 @@ START_TEST(propsys) test_propertystore(); test_PSCreatePropertyStoreFromObject(); test_InitVariantFromFileTime(); + test_VariantToStringWithDefault(); }
On 3/25/22 04:44, Mohamad Al-Jaf wrote:
- /* VT_BSTR */
- V_VT(&var) = VT_BSTR;
- V_BSTR(&var) = NULL;
- result = VariantToStringWithDefault(&var, default_value);
- ok(!lstrcmpW(result, wstr_empty), "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(!lstrcmpW(result, wstr_empty), "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(!lstrcmpW(result, wstr_space), "Unexpected value %s\n", wine_dbgstr_w(result));
- SysFreeString(V_BSTR(&var));
- V_VT(&var) = VT_BSTR;
- V_BSTR(&var) = SysAllocString(wstr_test2);
- result = VariantToStringWithDefault(&var, default_value);
- ok(!lstrcmpW(result, wstr_test2), "Unexpected value %s\n", wine_dbgstr_w(result));
- SysFreeString(V_BSTR(&var));
What you need to test is returned pointer value.
What you need to test is returned pointer value.
Could you please explain further? The test is based on test_PropVariantToStringWithDefault which also has a LPCWSTR and compares the string result. Isn't this already testing the returned value? -- Kind regards, Mohamad
On 3/25/22 04:44, Mohamad Al-Jaf wrote:
+/******************************************************************
- VariantToStringWithDefault (PROPSYS.@)
- */
+PCWSTR WINAPI VariantToStringWithDefault(const VARIANT *pvar, LPCWSTR pszDefault) +{
- TRACE("(%p, %s)\n", pvar, debugstr_w(pszDefault));
- if (V_VT(pvar) == VT_BSTR)
- {
if (V_BSTR(pvar) == NULL)
return L"";
return V_BSTR(pvar);
- }
- return pszDefault;
+}
This feels incomplete. There is at least a BYREF case, but also it's possible to have a nested variant ref.