Commit c66b5ac4 authored by Vincent Povirk's avatar Vincent Povirk Committed by Alexandre Julliard

propsys: Implement prop variant integer conversions with tests.

parent 6d52262e
...@@ -120,15 +120,15 @@ ...@@ -120,15 +120,15 @@
@ stub PropVariantToFileTimeVector @ stub PropVariantToFileTimeVector
@ stub PropVariantToFileTimeVectorAlloc @ stub PropVariantToFileTimeVectorAlloc
@ stdcall PropVariantToGUID(ptr ptr) @ stdcall PropVariantToGUID(ptr ptr)
@ stub PropVariantToInt16 @ stdcall PropVariantToInt16(ptr ptr)
@ stub PropVariantToInt16Vector @ stub PropVariantToInt16Vector
@ stub PropVariantToInt16VectorAlloc @ stub PropVariantToInt16VectorAlloc
@ stub PropVariantToInt16WithDefault @ stub PropVariantToInt16WithDefault
@ stub PropVariantToInt32 @ stdcall PropVariantToInt32(ptr ptr)
@ stub PropVariantToInt32Vector @ stub PropVariantToInt32Vector
@ stub PropVariantToInt32VectorAlloc @ stub PropVariantToInt32VectorAlloc
@ stub PropVariantToInt32WithDefault @ stub PropVariantToInt32WithDefault
@ stub PropVariantToInt64 @ stdcall PropVariantToInt64(ptr ptr)
@ stub PropVariantToInt64Vector @ stub PropVariantToInt64Vector
@ stub PropVariantToInt64VectorAlloc @ stub PropVariantToInt64VectorAlloc
@ stub PropVariantToInt64WithDefault @ stub PropVariantToInt64WithDefault
...@@ -138,15 +138,15 @@ ...@@ -138,15 +138,15 @@
@ stub PropVariantToStringVector @ stub PropVariantToStringVector
@ stub PropVariantToStringVectorAlloc @ stub PropVariantToStringVectorAlloc
@ stub PropVariantToStringWithDefault @ stub PropVariantToStringWithDefault
@ stub PropVariantToUInt16 @ stdcall PropVariantToUInt16(ptr ptr)
@ stub PropVariantToUInt16Vector @ stub PropVariantToUInt16Vector
@ stub PropVariantToUInt16VectorAlloc @ stub PropVariantToUInt16VectorAlloc
@ stub PropVariantToUInt16WithDefault @ stub PropVariantToUInt16WithDefault
@ stub PropVariantToUInt32 @ stdcall PropVariantToUInt32(ptr ptr)
@ stub PropVariantToUInt32Vector @ stub PropVariantToUInt32Vector
@ stub PropVariantToUInt32VectorAlloc @ stub PropVariantToUInt32VectorAlloc
@ stub PropVariantToUInt32WithDefault @ stub PropVariantToUInt32WithDefault
@ stub PropVariantToUInt64 @ stdcall PropVariantToUInt64(ptr ptr)
@ stub PropVariantToUInt64Vector @ stub PropVariantToUInt64Vector
@ stub PropVariantToUInt64VectorAlloc @ stub PropVariantToUInt64VectorAlloc
@ stub PropVariantToUInt64WithDefault @ stub PropVariantToUInt64WithDefault
......
...@@ -68,6 +68,147 @@ static HRESULT PROPVAR_ConvertFILETIME(PROPVARIANT *ppropvarDest, ...@@ -68,6 +68,147 @@ static HRESULT PROPVAR_ConvertFILETIME(PROPVARIANT *ppropvarDest,
return E_FAIL; return E_FAIL;
} }
static HRESULT PROPVAR_ConvertNumber(REFPROPVARIANT pv, int dest_bits,
int dest_signed, LONGLONG *res)
{
int src_signed;
switch (pv->vt)
{
case VT_I1:
src_signed = 1;
*res = pv->u.cVal;
break;
case VT_UI1:
src_signed = 0;
*res = pv->u.bVal;
break;
case VT_I2:
src_signed = 1;
*res = pv->u.iVal;
break;
case VT_UI2:
src_signed = 0;
*res = pv->u.uiVal;
break;
case VT_I4:
src_signed = 1;
*res = pv->u.lVal;
break;
case VT_UI4:
src_signed = 0;
*res = pv->u.ulVal;
break;
case VT_I8:
src_signed = 1;
*res = pv->u.hVal.QuadPart;
break;
case VT_UI8:
src_signed = 0;
*res = pv->u.uhVal.QuadPart;
break;
case VT_EMPTY:
src_signed = 0;
*res = 0;
break;
default:
FIXME("unhandled vt %d\n", pv->vt);
return E_NOTIMPL;
}
if (*res < 0 && src_signed != dest_signed)
return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW);
if (dest_bits < 64)
{
if (dest_signed)
{
if (*res >= ((LONGLONG)1 << (dest_bits-1)) ||
*res < ((LONGLONG)-1 << (dest_bits-1)))
return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW);
}
else
{
if ((ULONGLONG)(*res) >= ((ULONGLONG)1 << dest_bits))
return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW);
}
}
return S_OK;
}
HRESULT WINAPI PropVariantToInt16(REFPROPVARIANT propvarIn, SHORT *ret)
{
LONGLONG res;
HRESULT hr;
TRACE("%p,%p\n", propvarIn, ret);
hr = PROPVAR_ConvertNumber(propvarIn, 16, 1, &res);
if (SUCCEEDED(hr)) *ret = (SHORT)res;
return hr;
}
HRESULT WINAPI PropVariantToInt32(REFPROPVARIANT propvarIn, LONG *ret)
{
LONGLONG res;
HRESULT hr;
TRACE("%p,%p\n", propvarIn, ret);
hr = PROPVAR_ConvertNumber(propvarIn, 32, 1, &res);
if (SUCCEEDED(hr)) *ret = (LONG)res;
return hr;
}
HRESULT WINAPI PropVariantToInt64(REFPROPVARIANT propvarIn, LONGLONG *ret)
{
LONGLONG res;
HRESULT hr;
TRACE("%p,%p\n", propvarIn, ret);
hr = PROPVAR_ConvertNumber(propvarIn, 64, 1, &res);
if (SUCCEEDED(hr)) *ret = (LONGLONG)res;
return hr;
}
HRESULT WINAPI PropVariantToUInt16(REFPROPVARIANT propvarIn, USHORT *ret)
{
LONGLONG res;
HRESULT hr;
TRACE("%p,%p\n", propvarIn, ret);
hr = PROPVAR_ConvertNumber(propvarIn, 16, 0, &res);
if (SUCCEEDED(hr)) *ret = (USHORT)res;
return hr;
}
HRESULT WINAPI PropVariantToUInt32(REFPROPVARIANT propvarIn, ULONG *ret)
{
LONGLONG res;
HRESULT hr;
TRACE("%p,%p\n", propvarIn, ret);
hr = PROPVAR_ConvertNumber(propvarIn, 32, 0, &res);
if (SUCCEEDED(hr)) *ret = (ULONG)res;
return hr;
}
HRESULT WINAPI PropVariantToUInt64(REFPROPVARIANT propvarIn, ULONGLONG *ret)
{
LONGLONG res;
HRESULT hr;
TRACE("%p,%p\n", propvarIn, ret);
hr = PROPVAR_ConvertNumber(propvarIn, 64, 0, &res);
if (SUCCEEDED(hr)) *ret = (ULONGLONG)res;
return hr;
}
/****************************************************************** /******************************************************************
* PropVariantChangeType (PROPSYS.@) * PropVariantChangeType (PROPSYS.@)
*/ */
......
...@@ -753,6 +753,131 @@ static void test_PropVariantCompare(void) ...@@ -753,6 +753,131 @@ static void test_PropVariantCompare(void)
SysFreeString(str_b.u.bstrVal); SysFreeString(str_b.u.bstrVal);
} }
static inline const char* debugstr_longlong(ULONGLONG ll)
{
static char string[17];
if (sizeof(ll) > sizeof(unsigned long) && ll >> 32)
sprintf(string, "%lx%08lx", (unsigned long)(ll >> 32), (unsigned long)ll);
else
sprintf(string, "%lx", (unsigned long)ll);
return string;
}
static void test_intconversions(void)
{
PROPVARIANT propvar;
SHORT sval;
USHORT usval;
LONG lval;
ULONG ulval;
LONGLONG llval;
ULONGLONG ullval;
HRESULT hr;
PropVariantClear(&propvar);
propvar.vt = VT_I8;
propvar.u.hVal.QuadPart = (LONGLONG)1 << 63;
hr = PropVariantToInt64(&propvar, &llval);
ok(hr == S_OK, "hr=%x\n", hr);
ok(llval == (LONGLONG)1 << 63, "got wrong value %s\n", debugstr_longlong(llval));
hr = PropVariantToUInt64(&propvar, &ullval);
ok(hr == HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW), "hr=%x\n", hr);
hr = PropVariantToInt32(&propvar, &lval);
ok(hr == HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW), "hr=%x\n", hr);
hr = PropVariantToUInt32(&propvar, &ulval);
ok(hr == HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW), "hr=%x\n", hr);
hr = PropVariantToInt16(&propvar, &sval);
ok(hr == HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW), "hr=%x\n", hr);
hr = PropVariantToUInt16(&propvar, &usval);
ok(hr == HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW), "hr=%x\n", hr);
propvar.vt = VT_UI8;
propvar.u.uhVal.QuadPart = 5;
hr = PropVariantToInt64(&propvar, &llval);
ok(hr == S_OK, "hr=%x\n", hr);
ok(llval == 5, "got wrong value %s\n", debugstr_longlong(llval));
hr = PropVariantToUInt64(&propvar, &ullval);
ok(hr == S_OK, "hr=%x\n", hr);
ok(ullval == 5, "got wrong value %s\n", debugstr_longlong(ullval));
hr = PropVariantToInt32(&propvar, &lval);
ok(hr == S_OK, "hr=%x\n", hr);
ok(lval == 5, "got wrong value %d\n", lval);
hr = PropVariantToUInt32(&propvar, &ulval);
ok(hr == S_OK, "hr=%x\n", hr);
ok(ulval == 5, "got wrong value %d\n", ulval);
hr = PropVariantToInt16(&propvar, &sval);
ok(hr == S_OK, "hr=%x\n", hr);
ok(sval == 5, "got wrong value %d\n", sval);
hr = PropVariantToUInt16(&propvar, &usval);
ok(hr == S_OK, "hr=%x\n", hr);
ok(usval == 5, "got wrong value %d\n", usval);
propvar.vt = VT_I8;
propvar.u.hVal.QuadPart = -5;
hr = PropVariantToInt64(&propvar, &llval);
ok(hr == S_OK, "hr=%x\n", hr);
ok(llval == -5, "got wrong value %s\n", debugstr_longlong(llval));
hr = PropVariantToUInt64(&propvar, &ullval);
ok(hr == HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW), "hr=%x\n", hr);
hr = PropVariantToInt32(&propvar, &lval);
ok(hr == S_OK, "hr=%x\n", hr);
ok(lval == -5, "got wrong value %d\n", lval);
hr = PropVariantToUInt32(&propvar, &ulval);
ok(hr == HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW), "hr=%x\n", hr);
hr = PropVariantToInt16(&propvar, &sval);
ok(hr == S_OK, "hr=%x\n", hr);
ok(sval == -5, "got wrong value %d\n", sval);
hr = PropVariantToUInt16(&propvar, &usval);
ok(hr == HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW), "hr=%x\n", hr);
propvar.vt = VT_UI4;
propvar.u.ulVal = 6;
hr = PropVariantToInt64(&propvar, &llval);
ok(hr == S_OK, "hr=%x\n", hr);
ok(llval == 6, "got wrong value %s\n", debugstr_longlong(llval));
propvar.vt = VT_I4;
propvar.u.lVal = -6;
hr = PropVariantToInt64(&propvar, &llval);
ok(hr == S_OK, "hr=%x\n", hr);
ok(llval == -6, "got wrong value %s\n", debugstr_longlong(llval));
propvar.vt = VT_UI2;
propvar.u.uiVal = 7;
hr = PropVariantToInt64(&propvar, &llval);
ok(hr == S_OK, "hr=%x\n", hr);
ok(llval == 7, "got wrong value %s\n", debugstr_longlong(llval));
propvar.vt = VT_I2;
propvar.u.iVal = -7;
hr = PropVariantToInt64(&propvar, &llval);
ok(hr == S_OK, "hr=%x\n", hr);
ok(llval == -7, "got wrong value %s\n", debugstr_longlong(llval));
}
START_TEST(propsys) START_TEST(propsys)
{ {
test_PSStringFromPropertyKey(); test_PSStringFromPropertyKey();
...@@ -762,4 +887,5 @@ START_TEST(propsys) ...@@ -762,4 +887,5 @@ START_TEST(propsys)
test_InitPropVariantFromBuffer(); test_InitPropVariantFromBuffer();
test_PropVariantToGUID(); test_PropVariantToGUID();
test_PropVariantCompare(); test_PropVariantCompare();
test_intconversions();
} }
...@@ -70,6 +70,12 @@ HRESULT WINAPI VariantToGUID(const VARIANT *pvar, GUID *guid); ...@@ -70,6 +70,12 @@ HRESULT WINAPI VariantToGUID(const VARIANT *pvar, GUID *guid);
INT WINAPI PropVariantCompareEx(REFPROPVARIANT propvar1, REFPROPVARIANT propvar2, INT WINAPI PropVariantCompareEx(REFPROPVARIANT propvar1, REFPROPVARIANT propvar2,
PROPVAR_COMPARE_UNIT uint, PROPVAR_COMPARE_FLAGS flags); PROPVAR_COMPARE_UNIT uint, PROPVAR_COMPARE_FLAGS flags);
HRESULT WINAPI PropVariantToInt16(REFPROPVARIANT propvarIn, SHORT *ret);
HRESULT WINAPI PropVariantToInt32(REFPROPVARIANT propvarIn, LONG *ret);
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);
#ifdef __cplusplus #ifdef __cplusplus
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment