Signed-off-by: Jactry Zeng jzeng@codeweavers.com --- dlls/propsys/propsys.spec | 2 +- dlls/propsys/propvar.c | 26 +++++++++ dlls/propsys/tests/propsys.c | 106 +++++++++++++++++++++++++++++++++++ include/propvarutil.h | 1 + 4 files changed, 134 insertions(+), 1 deletion(-)
diff --git a/dlls/propsys/propsys.spec b/dlls/propsys/propsys.spec index d9347e27ae..8416b6dc74 100644 --- a/dlls/propsys/propsys.spec +++ b/dlls/propsys/propsys.spec @@ -111,7 +111,7 @@ @ stub PropVariantToBooleanVector @ stub PropVariantToBooleanVectorAlloc @ stub PropVariantToBooleanWithDefault -@ stub PropVariantToBuffer +@ stdcall PropVariantToBuffer(ptr ptr long) @ stdcall PropVariantToDouble(ptr ptr) @ stub PropVariantToDoubleVector @ stub PropVariantToDoubleVectorAlloc diff --git a/dlls/propsys/propvar.c b/dlls/propsys/propvar.c index 988cf81971..c56a737ede 100644 --- a/dlls/propsys/propvar.c +++ b/dlls/propsys/propvar.c @@ -306,6 +306,32 @@ HRESULT WINAPI PropVariantToBoolean(REFPROPVARIANT propvarIn, BOOL *ret) return hr; }
+HRESULT WINAPI PropVariantToBuffer(REFPROPVARIANT propvarIn, void *ret, UINT cb) +{ + HRESULT hr = S_OK; + + TRACE("(%p, %p, %d)\n", propvarIn, ret, cb); + + switch(propvarIn->vt) + { + case VT_VECTOR|VT_UI1: + if(cb > propvarIn->u.caub.cElems) + return E_FAIL; + memcpy(ret, propvarIn->u.caub.pElems, cb); + break; + case VT_ARRAY|VT_UI1: + FIXME("Unsupported type: VT_ARRAY|VT_UI1\n"); + hr = E_NOTIMPL; + break; + default: + WARN("Unexpected type: %x\n", propvarIn->vt); + hr = E_INVALIDARG; + } + + return hr; +} + + HRESULT WINAPI PropVariantToString(REFPROPVARIANT propvarIn, PWSTR ret, UINT cch) { HRESULT hr; diff --git a/dlls/propsys/tests/propsys.c b/dlls/propsys/tests/propsys.c index 059b622544..c47729ea97 100644 --- a/dlls/propsys/tests/propsys.c +++ b/dlls/propsys/tests/propsys.c @@ -1407,6 +1407,111 @@ static void test_PropVariantToString(void) SysFreeString(propvar.u.bstrVal); }
+static void test_PropVariantToBuffer(void) +{ + PROPVARIANT propvar; + HRESULT hr; + UINT8 data[] = {1,2,3,4,5,6,7,8,9,10}; + INT8 data_int8[] = {1,2,3,4,5,6,7,8,9,10}; + SAFEARRAY *sa; + SAFEARRAYBOUND sabound; + void *pdata; + UINT8 buffer[256]; + + hr = InitPropVariantFromBuffer(data, 10, &propvar); + ok(hr == S_OK, "InitVariantFromBuffer failed 0x%08x.\n", hr); + hr = PropVariantToBuffer(&propvar, NULL, 0); /* crash when cb isn't zero */ + ok(hr == S_OK, "PropVariantToBuffer failed: 0x%08x.\n", hr); + PropVariantClear(&propvar); + + hr = InitPropVariantFromBuffer(data, 10, &propvar); + ok(hr == S_OK, "InitVariantFromBuffer failed 0x%08x.\n", hr); + hr = PropVariantToBuffer(&propvar, buffer, 10); + ok(hr == S_OK, "PropVariantToBuffer failed: 0x%08x.\n", hr); + ok(!memcmp(buffer, data, 10) && !buffer[10], "got wrong buffer.\n"); + memset(buffer, 0, sizeof(buffer)); + PropVariantClear(&propvar); + + hr = InitPropVariantFromBuffer(data, 10, &propvar); + ok(hr == S_OK, "InitVariantFromBuffer failed 0x%08x.\n", hr); + buffer[0] = 99; + hr = PropVariantToBuffer(&propvar, buffer, 11); + ok(hr == E_FAIL, "PropVariantToBuffer returned: 0x%08x.\n", hr); + ok(buffer[0] == 99, "got wrong buffer.\n"); + memset(buffer, 0, sizeof(buffer)); + PropVariantClear(&propvar); + + hr = InitPropVariantFromBuffer(data, 10, &propvar); + ok(hr == S_OK, "InitVariantFromBuffer failed 0x%08x.\n", hr); + hr = PropVariantToBuffer(&propvar, buffer, 9); + ok(hr == S_OK, "PropVariantToBuffer failed: 0x%08x.\n", hr); + ok(!memcmp(buffer, data, 9) && !buffer[9], "got wrong buffer.\n"); + memset(buffer, 0, sizeof(buffer)); + PropVariantClear(&propvar); + + PropVariantInit(&propvar); + propvar.vt = VT_ARRAY|VT_UI1; + sabound.lLbound = 0; + sabound.cElements = sizeof(data); + sa = NULL; + sa = SafeArrayCreate(VT_UI1, 1, &sabound); + ok(sa != NULL, "SafeArrayCreate failed.\n"); + hr = SafeArrayAccessData(sa, &pdata); + ok(hr == S_OK, "SafeArrayAccessData failed: 0x%08x.\n", hr); + memcpy(pdata, data, sizeof(data)); + U(propvar).parray = sa; + buffer[0] = 99; + hr = PropVariantToBuffer(&propvar, buffer, 11); + todo_wine ok(hr == E_FAIL, "PropVariantToBuffer returned: 0x%08x.\n", hr); + ok(buffer[0] == 99, "got wrong buffer.\n"); + memset(buffer, 0, sizeof(buffer)); + SafeArrayDestroy(sa); + PropVariantClear(&propvar); + + PropVariantInit(&propvar); + propvar.vt = VT_ARRAY|VT_UI1; + sabound.lLbound = 0; + sabound.cElements = sizeof(data); + sa = NULL; + sa = SafeArrayCreate(VT_UI1, 1, &sabound); + ok(sa != NULL, "SafeArrayCreate failed.\n"); + hr = SafeArrayAccessData(sa, &pdata); + ok(hr == S_OK, "SafeArrayAccessData failed: 0x%08x.\n", hr); + memcpy(pdata, data, sizeof(data)); + U(propvar).parray = sa; + hr = PropVariantToBuffer(&propvar, buffer, sizeof(data)); + todo_wine ok(hr == S_OK, "PropVariantToBuffer failed: 0x%08x.\n", hr); + todo_wine ok(!memcmp(buffer, data, 10) && !buffer[10], "got wrong buffer.\n"); + memset(buffer, 0, sizeof(buffer)); + SafeArrayDestroy(sa); + PropVariantClear(&propvar); + + PropVariantInit(&propvar); + propvar.vt = VT_VECTOR|VT_I1; + U(propvar).caub.pElems = CoTaskMemAlloc(sizeof(data_int8)); + U(propvar).caub.cElems = sizeof(data_int8); + memcpy(U(propvar).caub.pElems, data_int8, sizeof(data_int8)); + hr = PropVariantToBuffer(&propvar, buffer, sizeof(data_int8)); + ok(hr == E_INVALIDARG, "PropVariantToBuffer failed: 0x%08x.\n", hr); + PropVariantClear(&propvar); + + PropVariantInit(&propvar); + propvar.vt = VT_ARRAY|VT_I1; + sabound.lLbound = 0; + sabound.cElements = sizeof(data_int8); + sa = NULL; + sa = SafeArrayCreate(VT_I1, 1, &sabound); + ok(sa != NULL, "SafeArrayCreate failed.\n"); + hr = SafeArrayAccessData(sa, &pdata); + ok(hr == S_OK, "SafeArrayAccessData failed: 0x%08x.\n", hr); + memcpy(pdata, data_int8, sizeof(data_int8)); + U(propvar).parray = sa; + hr = PropVariantToBuffer(&propvar, buffer, sizeof(data_int8)); + ok(hr == E_INVALIDARG, "PropVariantToBuffer failed: 0x%08x.\n", hr); + SafeArrayDestroy(sa); + PropVariantClear(&propvar); +} + START_TEST(propsys) { test_PSStringFromPropertyKey(); @@ -1424,4 +1529,5 @@ START_TEST(propsys) test_InitPropVariantFromCLSID(); test_PropVariantToDouble(); test_PropVariantToString(); + test_PropVariantToBuffer(); } diff --git a/include/propvarutil.h b/include/propvarutil.h index 4fb12d87eb..a4eedefdb6 100644 --- a/include/propvarutil.h +++ b/include/propvarutil.h @@ -79,6 +79,7 @@ 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 PropVariantToBuffer(REFPROPVARIANT propvarIn, void *ret, UINT cb); HRESULT WINAPI PropVariantToString(REFPROPVARIANT propvarIn, PWSTR ret, UINT cch); PCWSTR WINAPI PropVariantToStringWithDefault(REFPROPVARIANT propvarIn, LPCWSTR pszDefault);