propsys: Implement prop variant integer conversions with tests.
This commit is contained in:
parent
6d52262e56
commit
c66b5ac4c3
|
@ -120,15 +120,15 @@
|
|||
@ stub PropVariantToFileTimeVector
|
||||
@ stub PropVariantToFileTimeVectorAlloc
|
||||
@ stdcall PropVariantToGUID(ptr ptr)
|
||||
@ stub PropVariantToInt16
|
||||
@ stdcall PropVariantToInt16(ptr ptr)
|
||||
@ stub PropVariantToInt16Vector
|
||||
@ stub PropVariantToInt16VectorAlloc
|
||||
@ stub PropVariantToInt16WithDefault
|
||||
@ stub PropVariantToInt32
|
||||
@ stdcall PropVariantToInt32(ptr ptr)
|
||||
@ stub PropVariantToInt32Vector
|
||||
@ stub PropVariantToInt32VectorAlloc
|
||||
@ stub PropVariantToInt32WithDefault
|
||||
@ stub PropVariantToInt64
|
||||
@ stdcall PropVariantToInt64(ptr ptr)
|
||||
@ stub PropVariantToInt64Vector
|
||||
@ stub PropVariantToInt64VectorAlloc
|
||||
@ stub PropVariantToInt64WithDefault
|
||||
|
@ -138,15 +138,15 @@
|
|||
@ stub PropVariantToStringVector
|
||||
@ stub PropVariantToStringVectorAlloc
|
||||
@ stub PropVariantToStringWithDefault
|
||||
@ stub PropVariantToUInt16
|
||||
@ stdcall PropVariantToUInt16(ptr ptr)
|
||||
@ stub PropVariantToUInt16Vector
|
||||
@ stub PropVariantToUInt16VectorAlloc
|
||||
@ stub PropVariantToUInt16WithDefault
|
||||
@ stub PropVariantToUInt32
|
||||
@ stdcall PropVariantToUInt32(ptr ptr)
|
||||
@ stub PropVariantToUInt32Vector
|
||||
@ stub PropVariantToUInt32VectorAlloc
|
||||
@ stub PropVariantToUInt32WithDefault
|
||||
@ stub PropVariantToUInt64
|
||||
@ stdcall PropVariantToUInt64(ptr ptr)
|
||||
@ stub PropVariantToUInt64Vector
|
||||
@ stub PropVariantToUInt64VectorAlloc
|
||||
@ stub PropVariantToUInt64WithDefault
|
||||
|
|
|
@ -68,6 +68,147 @@ static HRESULT PROPVAR_ConvertFILETIME(PROPVARIANT *ppropvarDest,
|
|||
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.@)
|
||||
*/
|
||||
|
|
|
@ -753,6 +753,131 @@ static void test_PropVariantCompare(void)
|
|||
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)
|
||||
{
|
||||
test_PSStringFromPropertyKey();
|
||||
|
@ -762,4 +887,5 @@ START_TEST(propsys)
|
|||
test_InitPropVariantFromBuffer();
|
||||
test_PropVariantToGUID();
|
||||
test_PropVariantCompare();
|
||||
test_intconversions();
|
||||
}
|
||||
|
|
|
@ -70,6 +70,12 @@ HRESULT WINAPI VariantToGUID(const VARIANT *pvar, GUID *guid);
|
|||
INT WINAPI PropVariantCompareEx(REFPROPVARIANT propvar1, REFPROPVARIANT propvar2,
|
||||
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
|
||||
|
||||
|
|
Loading…
Reference in New Issue