From: Ziqing Hui zhui@codeweavers.com
--- dlls/propsys/propvar.c | 81 +++++++++++++++++++++++++++++++++++- dlls/propsys/tests/propsys.c | 11 ----- 2 files changed, 80 insertions(+), 12 deletions(-)
diff --git a/dlls/propsys/propvar.c b/dlls/propsys/propvar.c index 038222daafd..6500926380f 100644 --- a/dlls/propsys/propvar.c +++ b/dlls/propsys/propvar.c @@ -36,6 +36,26 @@
WINE_DEFAULT_DEBUG_CHANNEL(propsys);
+static HRESULT VARIANT_ValidateType(VARTYPE vt) +{ + VARTYPE vtExtra = vt & (VT_VECTOR | VT_ARRAY | VT_BYREF | VT_RESERVED); + + vt &= VT_TYPEMASK; + + if (!(vtExtra & (VT_VECTOR | VT_RESERVED))) + { + if (vt < VT_VOID || vt == VT_RECORD || vt == VT_CLSID) + { + if ((vtExtra & (VT_BYREF | VT_ARRAY)) && vt <= VT_NULL) + return DISP_E_BADVARTYPE; + if (vt != (VARTYPE)15) + return S_OK; + } + } + + return DISP_E_BADVARTYPE; +} + static HRESULT PROPVAR_ConvertFILETIME(const FILETIME *ft, PROPVARIANT *ppropvarDest, VARTYPE vt) { SYSTEMTIME time; @@ -1033,5 +1053,64 @@ HRESULT WINAPI PropVariantToVariant(const PROPVARIANT *propvar, VARIANT *var)
HRESULT WINAPI VariantToPropVariant(const VARIANT *var, PROPVARIANT *propvar) { - return E_NOTIMPL; + HRESULT hr; + + TRACE("var %p, propvar %p, var->vt %04x.\n", var, propvar, var->vt); + + if (!var || !propvar) + return E_INVALIDARG; + + if (FAILED(hr = VARIANT_ValidateType(var->vt))) + return hr; + + PropVariantInit(propvar); + propvar->vt = var->vt; + + switch (var->vt) + { + case VT_EMPTY: + case VT_NULL: + break; + case VT_I1: + propvar->cVal = V_I1(var); + break; + case VT_I2: + propvar->iVal = V_I2(var); + break; + case VT_I4: + propvar->lVal = V_I4(var); + break; + case VT_I8: + propvar->hVal.QuadPart = V_I8(var); + break; + case VT_UI1: + propvar->bVal = V_UI1(var); + break; + case VT_UI2: + propvar->uiVal = V_UI2(var); + break; + case VT_UI4: + propvar->ulVal = V_UI4(var); + break; + case VT_UI8: + propvar->uhVal.QuadPart = V_UI8(var); + break; + case VT_BOOL: + propvar->boolVal = V_BOOL(var); + break; + case VT_R4: + propvar->fltVal = V_R4(var); + break; + case VT_R8: + propvar->dblVal = V_R8(var); + break; + case VT_BSTR: + propvar->bstrVal = SysAllocString(V_BSTR(var)); + break; + default: + FIXME("Unsupported type %d.\n", var->vt); + return E_INVALIDARG; + } + + return S_OK; } diff --git a/dlls/propsys/tests/propsys.c b/dlls/propsys/tests/propsys.c index fded4b13879..fa0badef653 100644 --- a/dlls/propsys/tests/propsys.c +++ b/dlls/propsys/tests/propsys.c @@ -2343,15 +2343,12 @@ static void test_VariantToPropVariant(void) PropVariantInit(&propvar);
hr = VariantToPropVariant(NULL, &propvar); - todo_wine ok(hr == E_INVALIDARG, "VariantToPropVariant returned %#lx.\n", hr); hr = VariantToPropVariant(&var, NULL); - todo_wine ok(hr == E_INVALIDARG, "VariantToPropVariant returned %#lx.\n", hr);
V_VT(&var) = 0xdead; hr = VariantToPropVariant(&var, &propvar); - todo_wine ok(hr == DISP_E_BADVARTYPE, "VariantToPropVariant returned %#lx.\n", hr); V_VT(&var) = VT_ILLEGAL; hr = VariantToPropVariant(&var, &propvar); @@ -2364,12 +2361,9 @@ static void test_VariantToPropVariant(void)
V_VT(&var) = VT_EMPTY; hr = VariantToPropVariant(&var, &propvar); - todo_wine ok(hr == S_OK, "VariantToPropVariant returned %#lx.\n", hr); ok(propvar.vt == VT_EMPTY, "Unexpected propvar.vt %d.\n", propvar.vt);
- todo_wine - { V_VT(&var) = VT_NULL; hr = VariantToPropVariant(&var, &propvar); ok(hr == S_OK, "VariantToPropVariant returned %#lx.\n", hr); @@ -2389,19 +2383,14 @@ static void test_VariantToPropVariant(void)
check_VariantToPropVariant(var, propvar, R4, fltVal, 0.123f, "%f"); check_VariantToPropVariant(var, propvar, R8, dblVal, 0.456f, "%f"); - }
V_VT(&var) = VT_BSTR; V_BSTR(&var) = SysAllocString(L"test"); hr = VariantToPropVariant(&var, &propvar); - todo_wine ok(hr == S_OK, "VariantToPropVariant returned %#lx.\n", hr); - if (hr == S_OK) - { ok(propvar.vt == VT_BSTR, "Unexpected propvar.vt %d.\n", propvar.vt); ok(propvar.bstrVal != V_BSTR(&var), "Got same string pointer.\n"); ok(!wcscmp(propvar.bstrVal, V_BSTR(&var)), "Unexpected propvar.bstrVal %s.\n", debugstr_w(propvar.bstrVal)); - }
PropVariantClear(&propvar); VariantClear(&var);