diff --git a/dlls/propsys/propsys.spec b/dlls/propsys/propsys.spec index 582308f5a04..86a5e696eb5 100644 --- a/dlls/propsys/propsys.spec +++ b/dlls/propsys/propsys.spec @@ -107,7 +107,7 @@ @ stub PropVariantGetUInt32Elem @ stub PropVariantGetUInt64Elem @ stub PropVariantToBSTR -@ stub PropVariantToBoolean +@ stdcall PropVariantToBoolean(ptr ptr) @ stub PropVariantToBooleanVector @ stub PropVariantToBooleanVectorAlloc @ stub PropVariantToBooleanWithDefault diff --git a/dlls/propsys/propvar.c b/dlls/propsys/propvar.c index ca3b421ddda..bdf92269890 100644 --- a/dlls/propsys/propvar.c +++ b/dlls/propsys/propvar.c @@ -227,6 +227,66 @@ HRESULT WINAPI PropVariantToUInt64(REFPROPVARIANT propvarIn, ULONGLONG *ret) return hr; } +HRESULT WINAPI PropVariantToBoolean(REFPROPVARIANT propvarIn, BOOL *ret) +{ + static const WCHAR trueW[] = {'t','r','u','e',0}; + static const WCHAR falseW[] = {'f','a','l','s','e',0}; + static const WCHAR true2W[] = {'#','T','R','U','E','#',0}; + static const WCHAR false2W[] = {'#','F','A','L','S','E','#',0}; + LONGLONG res; + HRESULT hr; + + TRACE("%p,%p\n", propvarIn, ret); + + *ret = FALSE; + + switch (propvarIn->vt) + { + case VT_BOOL: + *ret = propvarIn->u.boolVal == VARIANT_TRUE; + return S_OK; + + case VT_LPWSTR: + case VT_BSTR: + if (!propvarIn->u.pwszVal) + return DISP_E_TYPEMISMATCH; + + if (!lstrcmpiW(propvarIn->u.pwszVal, trueW) || !lstrcmpW(propvarIn->u.pwszVal, true2W)) + { + *ret = TRUE; + return S_OK; + } + + if (!lstrcmpiW(propvarIn->u.pwszVal, falseW) || !lstrcmpW(propvarIn->u.pwszVal, false2W)) + { + *ret = FALSE; + return S_OK; + } + break; + + case VT_LPSTR: + if (!propvarIn->u.pszVal) + return DISP_E_TYPEMISMATCH; + + if (!lstrcmpiA(propvarIn->u.pszVal, "true") || !lstrcmpA(propvarIn->u.pszVal, "#TRUE#")) + { + *ret = TRUE; + return S_OK; + } + + if (!lstrcmpiA(propvarIn->u.pszVal, "false") || !lstrcmpA(propvarIn->u.pszVal, "#FALSE#")) + { + *ret = FALSE; + return S_OK; + } + break; + } + + hr = PROPVAR_ConvertNumber(propvarIn, 64, FALSE, &res); + *ret = !!res; + return hr; +} + HRESULT WINAPI PropVariantToStringAlloc(REFPROPVARIANT propvarIn, WCHAR **ret) { WCHAR *res = NULL; diff --git a/dlls/propsys/tests/propsys.c b/dlls/propsys/tests/propsys.c index 776ccd0bfdf..ce1ee7138f4 100644 --- a/dlls/propsys/tests/propsys.c +++ b/dlls/propsys/tests/propsys.c @@ -883,6 +883,220 @@ static void test_intconversions(void) ok(llval == -7, "got wrong value %s\n", wine_dbgstr_longlong(llval)); } +static void test_PropVariantToBoolean(void) +{ + static WCHAR str_0[] = {'0',0}; + static WCHAR str_1[] = {'1',0}; + static WCHAR str_7[] = {'7',0}; + static WCHAR str_n7[] = {'-','7',0}; + static WCHAR str_true[] = {'t','r','u','e',0}; + static WCHAR str_true2[] = {'#','T','R','U','E','#',0}; + static WCHAR str_true_case[] = {'t','R','U','e',0}; + static WCHAR str_false[] = {'f','a','l','s','e',0}; + static WCHAR str_false2[] = {'#','F','A','L','S','E','#',0}; + static WCHAR str_true_space[] = {'t','r','u','e',' ',0}; + static WCHAR str_yes[] = {'y','e','s',0}; + PROPVARIANT propvar; + HRESULT hr; + BOOL val; + + /* VT_BOOL */ + propvar.vt = VT_BOOL; + propvar.u.boolVal = VARIANT_FALSE; + val = TRUE; + hr = PropVariantToBoolean(&propvar, &val); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(val == FALSE, "Unexpected value %d\n", val); + + propvar.vt = VT_BOOL; + propvar.u.boolVal = 1; + val = TRUE; + hr = PropVariantToBoolean(&propvar, &val); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(val == FALSE, "Unexpected value %d\n", val); + + propvar.vt = VT_BOOL; + propvar.u.boolVal = VARIANT_TRUE; + val = FALSE; + hr = PropVariantToBoolean(&propvar, &val); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(val == TRUE, "Unexpected value %d\n", val); + + /* VT_EMPTY */ + propvar.vt = VT_EMPTY; + propvar.u.boolVal = VARIANT_TRUE; + val = TRUE; + hr = PropVariantToBoolean(&propvar, &val); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(val == FALSE, "Unexpected value %d\n", val); + + /* test integer conversion */ + propvar.vt = VT_I4; + propvar.u.lVal = 0; + val = TRUE; + hr = PropVariantToBoolean(&propvar, &val); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(val == FALSE, "Unexpected value %d\n", val); + + propvar.vt = VT_I4; + propvar.u.lVal = 1; + val = FALSE; + hr = PropVariantToBoolean(&propvar, &val); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(val == TRUE, "Unexpected value %d\n", val); + + propvar.vt = VT_I4; + propvar.u.lVal = 67; + val = FALSE; + hr = PropVariantToBoolean(&propvar, &val); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(val == TRUE, "Unexpected value %d\n", val); + + propvar.vt = VT_I4; + propvar.u.lVal = -67; + val = FALSE; + hr = PropVariantToBoolean(&propvar, &val); +todo_wine + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(val == TRUE, "Unexpected value %d\n", val); + + /* test string conversion */ + propvar.vt = VT_LPWSTR; + propvar.u.pwszVal = str_0; + val = TRUE; + hr = PropVariantToBoolean(&propvar, &val); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(val == FALSE, "Unexpected value %d\n", val); + + propvar.vt = VT_LPWSTR; + propvar.u.pwszVal = str_1; + val = FALSE; + hr = PropVariantToBoolean(&propvar, &val); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(val == TRUE, "Unexpected value %d\n", val); + + propvar.vt = VT_LPWSTR; + propvar.u.pwszVal = str_7; + val = FALSE; + hr = PropVariantToBoolean(&propvar, &val); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(val == TRUE, "Unexpected value %d\n", val); + + propvar.vt = VT_LPWSTR; + propvar.u.pwszVal = str_n7; + val = FALSE; + hr = PropVariantToBoolean(&propvar, &val); +todo_wine + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(val == TRUE, "Unexpected value %d\n", val); + + propvar.vt = VT_LPWSTR; + propvar.u.pwszVal = str_true; + val = FALSE; + hr = PropVariantToBoolean(&propvar, &val); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(val == TRUE, "Unexpected value %d\n", val); + + propvar.vt = VT_LPWSTR; + propvar.u.pwszVal = str_true_case; + val = FALSE; + hr = PropVariantToBoolean(&propvar, &val); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(val == TRUE, "Unexpected value %d\n", val); + + propvar.vt = VT_LPWSTR; + propvar.u.pwszVal = str_true2; + val = FALSE; + hr = PropVariantToBoolean(&propvar, &val); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(val == TRUE, "Unexpected value %d\n", val); + + propvar.vt = VT_LPWSTR; + propvar.u.pwszVal = str_false; + val = TRUE; + hr = PropVariantToBoolean(&propvar, &val); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(val == FALSE, "Unexpected value %d\n", val); + + propvar.vt = VT_LPWSTR; + propvar.u.pwszVal = str_false2; + val = TRUE; + hr = PropVariantToBoolean(&propvar, &val); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(val == FALSE, "Unexpected value %d\n", val); + + propvar.vt = VT_LPWSTR; + propvar.u.pwszVal = str_true_space; + val = TRUE; + hr = PropVariantToBoolean(&propvar, &val); + ok(hr == DISP_E_TYPEMISMATCH, "Unexpected hr %#x.\n", hr); + ok(val == FALSE, "Unexpected value %d\n", val); + + propvar.vt = VT_LPWSTR; + propvar.u.pwszVal = str_yes; + val = TRUE; + hr = PropVariantToBoolean(&propvar, &val); + ok(hr == DISP_E_TYPEMISMATCH, "Unexpected hr %#x.\n", hr); + ok(val == FALSE, "Unexpected value %d\n", val); + + propvar.vt = VT_LPWSTR; + propvar.u.pwszVal = NULL; + val = TRUE; + hr = PropVariantToBoolean(&propvar, &val); + ok(hr == DISP_E_TYPEMISMATCH, "Unexpected hr %#x.\n", hr); + ok(val == FALSE, "Unexpected value %d\n", val); + + /* VT_LPSTR */ + propvar.vt = VT_LPSTR; + propvar.u.pszVal = (char *)"#TruE#"; + val = TRUE; + hr = PropVariantToBoolean(&propvar, &val); + ok(hr == DISP_E_TYPEMISMATCH, "Unexpected hr %#x.\n", hr); + ok(val == FALSE, "Unexpected value %d\n", val); + + propvar.vt = VT_LPSTR; + propvar.u.pszVal = (char *)"#TRUE#"; + val = FALSE; + hr = PropVariantToBoolean(&propvar, &val); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(val == TRUE, "Unexpected value %d\n", val); + + propvar.vt = VT_LPSTR; + propvar.u.pszVal = (char *)"tRUe"; + val = FALSE; + hr = PropVariantToBoolean(&propvar, &val); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(val == TRUE, "Unexpected value %d\n", val); + + propvar.vt = VT_LPSTR; + propvar.u.pszVal = (char *)"#FALSE#"; + val = TRUE; + hr = PropVariantToBoolean(&propvar, &val); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(val == FALSE, "Unexpected value %d\n", val); + + propvar.vt = VT_LPSTR; + propvar.u.pszVal = (char *)"fALSe"; + val = TRUE; + hr = PropVariantToBoolean(&propvar, &val); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(val == FALSE, "Unexpected value %d\n", val); + + propvar.vt = VT_LPSTR; + propvar.u.pszVal = (char *)"1"; + val = FALSE; + hr = PropVariantToBoolean(&propvar, &val); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(val == TRUE, "Unexpected value %d\n", val); + + propvar.vt = VT_LPSTR; + propvar.u.pszVal = (char *)"-1"; + hr = PropVariantToBoolean(&propvar, &val); +todo_wine + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(val == TRUE, "Unexpected value %d\n", val); +} + static void test_PropVariantChangeType_LPWSTR(void) { PROPVARIANT dest, src; @@ -931,4 +1145,5 @@ START_TEST(propsys) test_PropVariantCompare(); test_intconversions(); test_PropVariantChangeType_LPWSTR(); + test_PropVariantToBoolean(); } diff --git a/include/propvarutil.h b/include/propvarutil.h index d0aecdb872a..4dc3521a02c 100644 --- a/include/propvarutil.h +++ b/include/propvarutil.h @@ -76,6 +76,7 @@ HRESULT WINAPI PropVariantToInt64(REFPROPVARIANT propvarIn, LONGLONG *ret); HRESULT WINAPI PropVariantToUInt16(REFPROPVARIANT propvarIn, USHORT *ret); HRESULT WINAPI PropVariantToUInt32(REFPROPVARIANT propvarIn, ULONG *ret); HRESULT WINAPI PropVariantToUInt64(REFPROPVARIANT propvarIn, ULONGLONG *ret); +HRESULT WINAPI PropVariantToBoolean(REFPROPVARIANT propvarIn, BOOL *ret); HRESULT WINAPI PropVariantToStringAlloc(REFPROPVARIANT propvarIn, WCHAR **ret);