/*
 * Low level variant functions
 *
 * Copyright 2003 Jon Griffiths
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#define COBJMACROS
#define NONAMELESSUNION
#define NONAMELESSSTRUCT

#include "wine/debug.h"
#include "wine/unicode.h"
#include "winbase.h"
#include "winuser.h"
#include "winnt.h"
#include "variant.h"
#include "resource.h"

WINE_DEFAULT_DEBUG_CHANNEL(variant);

extern HMODULE OLEAUT32_hModule;

#define CY_MULTIPLIER   10000             /* 4 dp of precision */
#define CY_MULTIPLIER_F 10000.0
#define CY_HALF         (CY_MULTIPLIER/2) /* 0.5 */
#define CY_HALF_F       (CY_MULTIPLIER_F/2.0)

static const WCHAR szFloatFormatW[] = { '%','.','7','G','\0' };
static const WCHAR szDoubleFormatW[] = { '%','.','1','5','G','\0' };

/* Copy data from one variant to another. */
static inline void VARIANT_CopyData(const VARIANT *srcVar, VARTYPE vt, void *pOut)
{
  switch (vt)
  {
  case VT_I1:
  case VT_UI1: memcpy(pOut, &V_UI1(srcVar), sizeof(BYTE)); break;
  case VT_BOOL:
  case VT_I2:
  case VT_UI2: memcpy(pOut, &V_UI2(srcVar), sizeof(SHORT)); break;
  case VT_R4:
  case VT_INT:
  case VT_I4:
  case VT_UINT:
  case VT_UI4: memcpy(pOut, &V_UI4(srcVar), sizeof (LONG)); break;
  case VT_R8:
  case VT_DATE:
  case VT_CY:
  case VT_I8:
  case VT_UI8: memcpy(pOut, &V_UI8(srcVar), sizeof (LONG64)); break;
  case VT_INT_PTR: memcpy(pOut, &V_INT_PTR(srcVar), sizeof (INT_PTR)); break;
  case VT_DECIMAL: memcpy(pOut, &V_DECIMAL(srcVar), sizeof (DECIMAL)); break;
  default:
    FIXME("VT_ type %d unhandled, please report!\n", vt);
  }
}

/* Macro to inline conversion from a float or double to any integer type,
 * rounding according to the 'dutch' convention.
 */
#define VARIANT_DutchRound(typ, value, res) do { \
  double whole = value < 0 ? ceil(value) : floor(value); \
  double fract = value - whole; \
  if (fract > 0.5) res = (typ)whole + (typ)1; \
  else if (fract == 0.5) { typ is_odd = (typ)whole & 1; res = whole + is_odd; } \
  else if (fract >= 0.0) res = (typ)whole; \
  else if (fract == -0.5) { typ is_odd = (typ)whole & 1; res = whole - is_odd; } \
  else if (fract > -0.5) res = (typ)whole; \
  else res = (typ)whole - (typ)1; \
} while(0);


/* Coerce VT_BSTR to a numeric type */
static HRESULT VARIANT_NumberFromBstr(OLECHAR* pStrIn, LCID lcid, ULONG ulFlags,
                                      void* pOut, VARTYPE vt)
{
  VARIANTARG dstVar;
  HRESULT hRet;
  NUMPARSE np;
  BYTE rgb[1024];

  /* Use VarParseNumFromStr/VarNumFromParseNum as MSDN indicates */
  np.cDig = sizeof(rgb) / sizeof(BYTE);
  np.dwInFlags = NUMPRS_STD;

  hRet = VarParseNumFromStr(pStrIn, lcid, ulFlags, &np, rgb);

  if (SUCCEEDED(hRet))
  {
    /* 1 << vt gives us the VTBIT constant for the destination number type */
    hRet = VarNumFromParseNum(&np, rgb, 1 << vt, &dstVar);
    if (SUCCEEDED(hRet))
      VARIANT_CopyData(&dstVar, vt, pOut);
  }
  return hRet;
}

/* Coerce VT_DISPATCH to another type */
static HRESULT VARIANT_FromDisp(IDispatch* pdispIn, LCID lcid, void* pOut,
                                VARTYPE vt, DWORD dwFlags)
{
  static const DISPPARAMS emptyParams = { NULL, NULL, 0, 0 };
  VARIANTARG srcVar, dstVar;
  HRESULT hRet;

  if (!pdispIn)
    return DISP_E_BADVARTYPE;

  /* Get the default 'value' property from the IDispatch */
  hRet = IDispatch_Invoke(pdispIn, DISPID_VALUE, &IID_NULL, lcid, DISPATCH_PROPERTYGET,
                          (DISPPARAMS*)&emptyParams, &srcVar, NULL, NULL);

  if (SUCCEEDED(hRet))
  {
    /* Convert the property to the requested type */
    V_VT(&dstVar) = VT_EMPTY;
    hRet = VariantChangeTypeEx(&dstVar, &srcVar, lcid, dwFlags, vt);
    VariantClear(&srcVar);

    if (SUCCEEDED(hRet))
    {
      VARIANT_CopyData(&dstVar, vt, pOut);
      VariantClear(&srcVar);
    }
  }
  else
    hRet = DISP_E_TYPEMISMATCH;
  return hRet;
}

/* Inline return type */
#define RETTYP inline static HRESULT


/* Simple compiler cast from one type to another */
#define SIMPLE(dest, src, func) RETTYP _##func(src in, dest* out) { \
  *out = in; return S_OK; }

/* Compiler cast where input cannot be negative */
#define NEGTST(dest, src, func) RETTYP _##func(src in, dest* out) { \
  if (in < (src)0) return DISP_E_OVERFLOW; *out = in; return S_OK; }

/* Compiler cast where input cannot be > some number */
#define POSTST(dest, src, func, tst) RETTYP _##func(src in, dest* out) { \
  if (in > (dest)tst) return DISP_E_OVERFLOW; *out = in; return S_OK; }

/* Compiler cast where input cannot be < some number or >= some other number */
#define BOTHTST(dest, src, func, lo, hi) RETTYP _##func(src in, dest* out) { \
  if (in < (dest)lo || in > hi) return DISP_E_OVERFLOW; *out = in; return S_OK; }

/* I1 */
POSTST(signed char, BYTE, VarI1FromUI1, I1_MAX);
BOTHTST(signed char, SHORT, VarI1FromI2, I1_MIN, I1_MAX);
BOTHTST(signed char, LONG, VarI1FromI4, I1_MIN, I1_MAX);
SIMPLE(signed char, VARIANT_BOOL, VarI1FromBool);
POSTST(signed char, USHORT, VarI1FromUI2, I1_MAX);
POSTST(signed char, ULONG, VarI1FromUI4, I1_MAX);
BOTHTST(signed char, LONG64, VarI1FromI8, I1_MIN, I1_MAX);
POSTST(signed char, ULONG64, VarI1FromUI8, I1_MAX);

/* UI1 */
BOTHTST(BYTE, SHORT, VarUI1FromI2, UI1_MIN, UI1_MAX);
SIMPLE(BYTE, VARIANT_BOOL, VarUI1FromBool);
NEGTST(BYTE, signed char, VarUI1FromI1);
POSTST(BYTE, USHORT, VarUI1FromUI2, UI1_MAX);
BOTHTST(BYTE, LONG, VarUI1FromI4, UI1_MIN, UI1_MAX);
POSTST(BYTE, ULONG, VarUI1FromUI4, UI1_MAX);
BOTHTST(BYTE, LONG64, VarUI1FromI8, UI1_MIN, UI1_MAX);
POSTST(BYTE, ULONG64, VarUI1FromUI8, UI1_MAX);

/* I2 */
SIMPLE(SHORT, BYTE, VarI2FromUI1);
BOTHTST(SHORT, LONG, VarI2FromI4, I2_MIN, I2_MAX);
SIMPLE(SHORT, VARIANT_BOOL, VarI2FromBool);
SIMPLE(SHORT, signed char, VarI2FromI1);
POSTST(SHORT, USHORT, VarI2FromUI2, I2_MAX);
POSTST(SHORT, ULONG, VarI2FromUI4, I2_MAX);
BOTHTST(SHORT, LONG64, VarI2FromI8, I2_MIN, I2_MAX);
POSTST(SHORT, ULONG64, VarI2FromUI8, I2_MAX);

/* UI2 */
SIMPLE(USHORT, BYTE, VarUI2FromUI1);
NEGTST(USHORT, SHORT, VarUI2FromI2);
BOTHTST(USHORT, LONG, VarUI2FromI4, UI2_MIN, UI2_MAX);
SIMPLE(USHORT, VARIANT_BOOL, VarUI2FromBool);
NEGTST(USHORT, signed char, VarUI2FromI1);
POSTST(USHORT, ULONG, VarUI2FromUI4, UI2_MAX);
BOTHTST(USHORT, LONG64, VarUI2FromI8, UI2_MIN, UI2_MAX);
POSTST(USHORT, ULONG64, VarUI2FromUI8, UI2_MAX);

/* I4 */
SIMPLE(LONG, BYTE, VarI4FromUI1);
SIMPLE(LONG, SHORT, VarI4FromI2);
SIMPLE(LONG, VARIANT_BOOL, VarI4FromBool);
SIMPLE(LONG, signed char, VarI4FromI1);
SIMPLE(LONG, USHORT, VarI4FromUI2);
POSTST(LONG, ULONG, VarI4FromUI4, I4_MAX);
BOTHTST(LONG, LONG64, VarI4FromI8, I4_MIN, I4_MAX);
POSTST(LONG, ULONG64, VarI4FromUI8, I4_MAX);

/* UI4 */
SIMPLE(ULONG, BYTE, VarUI4FromUI1);
NEGTST(ULONG, SHORT, VarUI4FromI2);
NEGTST(ULONG, LONG, VarUI4FromI4);
SIMPLE(ULONG, VARIANT_BOOL, VarUI4FromBool);
NEGTST(ULONG, signed char, VarUI4FromI1);
SIMPLE(ULONG, USHORT, VarUI4FromUI2);
BOTHTST(ULONG, LONG64, VarUI4FromI8, UI4_MIN, UI4_MAX);
POSTST(ULONG, ULONG64, VarUI4FromUI8, UI4_MAX);

/* I8 */
SIMPLE(LONG64, BYTE, VarI8FromUI1);
SIMPLE(LONG64, SHORT, VarI8FromI2);
SIMPLE(LONG64, signed char, VarI8FromI1);
SIMPLE(LONG64, USHORT, VarI8FromUI2);
SIMPLE(LONG64, LONG, VarI8FromI4);
SIMPLE(LONG64, ULONG, VarI8FromUI4);
POSTST(LONG64, ULONG64, VarI8FromUI8, I8_MAX);

/* UI8 */
SIMPLE(ULONG64, BYTE, VarUI8FromUI1);
NEGTST(ULONG64, SHORT, VarUI8FromI2);
NEGTST(ULONG64, signed char, VarUI8FromI1);
SIMPLE(ULONG64, USHORT, VarUI8FromUI2);
NEGTST(ULONG64, LONG, VarUI8FromI4);
SIMPLE(ULONG64, ULONG, VarUI8FromUI4);
NEGTST(ULONG64, LONG64, VarUI8FromI8);

/* R4 (float) */
SIMPLE(float, BYTE, VarR4FromUI1);
SIMPLE(float, SHORT, VarR4FromI2);
SIMPLE(float, signed char, VarR4FromI1);
SIMPLE(float, USHORT, VarR4FromUI2);
SIMPLE(float, LONG, VarR4FromI4);
SIMPLE(float, ULONG, VarR4FromUI4);
SIMPLE(float, LONG64, VarR4FromI8);
SIMPLE(float, ULONG64, VarR4FromUI8);

/* R8 (double) */
SIMPLE(double, BYTE, VarR8FromUI1);
SIMPLE(double, SHORT, VarR8FromI2);
SIMPLE(double, float, VarR8FromR4);
RETTYP _VarR8FromCy(CY i, double* o) { *o = (double)i.int64 / CY_MULTIPLIER_F; return S_OK; }
SIMPLE(double, DATE, VarR8FromDate);
SIMPLE(double, signed char, VarR8FromI1);
SIMPLE(double, USHORT, VarR8FromUI2);
SIMPLE(double, LONG, VarR8FromI4);
SIMPLE(double, ULONG, VarR8FromUI4);
SIMPLE(double, LONG64, VarR8FromI8);
SIMPLE(double, ULONG64, VarR8FromUI8);


/* I1
 */

/************************************************************************
 * VarI1FromUI1 (OLEAUT32.244)
 *
 * Convert a VT_UI1 to a VT_I1.
 *
 * PARAMS
 *  bIn     [I] Source
 *  pcOut   [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if the source value is invalid
 *           DISP_E_OVERFLOW, if the value will not fit in the destination
 */
HRESULT WINAPI VarI1FromUI1(BYTE bIn, signed char* pcOut)
{
  return _VarI1FromUI1(bIn, pcOut);
}

/************************************************************************
 * VarI1FromI2 (OLEAUT32.245)
 *
 * Convert a VT_I2 to a VT_I1.
 *
 * PARAMS
 *  sIn     [I] Source
 *  pcOut   [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if the source value is invalid
 *           DISP_E_OVERFLOW, if the value will not fit in the destination
 */
HRESULT WINAPI VarI1FromI2(SHORT sIn, signed char* pcOut)
{
  return _VarI1FromI2(sIn, pcOut);
}

/************************************************************************
 * VarI1FromI4 (OLEAUT32.246)
 *
 * Convert a VT_I4 to a VT_I1.
 *
 * PARAMS
 *  iIn     [I] Source
 *  pcOut   [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if the source value is invalid
 *           DISP_E_OVERFLOW, if the value will not fit in the destination
 */
HRESULT WINAPI VarI1FromI4(LONG iIn, signed char* pcOut)
{
  return _VarI1FromI4(iIn, pcOut);
}

/************************************************************************
 * VarI1FromR4 (OLEAUT32.247)
 *
 * Convert a VT_R4 to a VT_I1.
 *
 * PARAMS
 *  fltIn   [I] Source
 *  pcOut   [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if the source value is invalid
 *           DISP_E_OVERFLOW, if the value will not fit in the destination
 */
HRESULT WINAPI VarI1FromR4(FLOAT fltIn, signed char* pcOut)
{
  return VarI1FromR8(fltIn, pcOut);
}

/************************************************************************
 * VarI1FromR8 (OLEAUT32.248)
 *
 * Convert a VT_R8 to a VT_I1.
 *
 * PARAMS
 *  dblIn   [I] Source
 *  pcOut   [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if the source value is invalid
 *           DISP_E_OVERFLOW, if the value will not fit in the destination
 *
 * NOTES
 *  See VarI8FromR8() for details concerning rounding.
 */
HRESULT WINAPI VarI1FromR8(double dblIn, signed char* pcOut)
{
  if (dblIn < (double)I1_MIN || dblIn > (double)I1_MAX)
    return DISP_E_OVERFLOW;
  VARIANT_DutchRound(CHAR, dblIn, *pcOut);
  return S_OK;
}

/************************************************************************
 * VarI1FromDate (OLEAUT32.249)
 *
 * Convert a VT_DATE to a VT_I1.
 *
 * PARAMS
 *  dateIn  [I] Source
 *  pcOut   [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if the source value is invalid
 *           DISP_E_OVERFLOW, if the value will not fit in the destination
 */
HRESULT WINAPI VarI1FromDate(DATE dateIn, signed char* pcOut)
{
  return VarI1FromR8(dateIn, pcOut);
}

/************************************************************************
 * VarI1FromCy (OLEAUT32.250)
 *
 * Convert a VT_CY to a VT_I1.
 *
 * PARAMS
 *  cyIn    [I] Source
 *  pcOut   [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if the source value is invalid
 *           DISP_E_OVERFLOW, if the value will not fit in the destination
 */
HRESULT WINAPI VarI1FromCy(CY cyIn, signed char* pcOut)
{
  LONG i = I1_MAX + 1;

  VarI4FromCy(cyIn, &i);
  return _VarI1FromI4(i, pcOut);
}

/************************************************************************
 * VarI1FromStr (OLEAUT32.251)
 *
 * Convert a VT_BSTR to a VT_I1.
 *
 * PARAMS
 *  strIn   [I] Source
 *  lcid    [I] LCID for the conversion
 *  dwFlags [I] Flags controlling the conversion (VAR_ flags from "oleauto.h")
 *  pcOut   [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if the source value is invalid
 *           DISP_E_OVERFLOW, if the value will not fit in the destination
 *           DISP_E_TYPEMISMATCH, if the type cannot be converted
 */
HRESULT WINAPI VarI1FromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, signed char* pcOut)
{
  return VARIANT_NumberFromBstr(strIn, lcid, dwFlags, pcOut, VT_I1);
}

/************************************************************************
 * VarI1FromDisp (OLEAUT32.252)
 *
 * Convert a VT_DISPATCH to a VT_I1.
 *
 * PARAMS
 *  pdispIn  [I] Source
 *  lcid     [I] LCID for conversion
 *  pcOut    [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if the source value is invalid
 *           DISP_E_OVERFLOW, if the value will not fit in the destination
 *           DISP_E_TYPEMISMATCH, if the type cannot be converted
 */
HRESULT WINAPI VarI1FromDisp(IDispatch* pdispIn, LCID lcid, signed char* pcOut)
{
  return VARIANT_FromDisp(pdispIn, lcid, pcOut, VT_I1, 0);
}

/************************************************************************
 * VarI1FromBool (OLEAUT32.253)
 *
 * Convert a VT_BOOL to a VT_I1.
 *
 * PARAMS
 *  boolIn  [I] Source
 *  pcOut   [O] Destination
 *
 * RETURNS
 *  S_OK.
 */
HRESULT WINAPI VarI1FromBool(VARIANT_BOOL boolIn, signed char* pcOut)
{
  return _VarI1FromBool(boolIn, pcOut);
}

/************************************************************************
 * VarI1FromUI2 (OLEAUT32.254)
 *
 * Convert a VT_UI2 to a VT_I1.
 *
 * PARAMS
 *  usIn    [I] Source
 *  pcOut   [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if the source value is invalid
 *           DISP_E_OVERFLOW, if the value will not fit in the destination
 */
HRESULT WINAPI VarI1FromUI2(USHORT usIn, signed char* pcOut)
{
  return _VarI1FromUI2(usIn, pcOut);
}

/************************************************************************
 * VarI1FromUI4 (OLEAUT32.255)
 *
 * Convert a VT_UI4 to a VT_I1.
 *
 * PARAMS
 *  ulIn    [I] Source
 *  pcOut   [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if the source value is invalid
 *           DISP_E_OVERFLOW, if the value will not fit in the destination
 *           DISP_E_TYPEMISMATCH, if the type cannot be converted
 */
HRESULT WINAPI VarI1FromUI4(ULONG ulIn, signed char* pcOut)
{
  return _VarI1FromUI4(ulIn, pcOut);
}

/************************************************************************
 * VarI1FromDec (OLEAUT32.256)
 *
 * Convert a VT_DECIMAL to a VT_I1.
 *
 * PARAMS
 *  pDecIn  [I] Source
 *  pcOut   [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if the source value is invalid
 *           DISP_E_OVERFLOW, if the value will not fit in the destination
 */
HRESULT WINAPI VarI1FromDec(DECIMAL *pdecIn, signed char* pcOut)
{
  LONG64 i64;
  HRESULT hRet;

  hRet = VarI8FromDec(pdecIn, &i64);

  if (SUCCEEDED(hRet))
    hRet = _VarI1FromI8(i64, pcOut);
  return hRet;
}

/************************************************************************
 * VarI1FromI8 (OLEAUT32.376)
 *
 * Convert a VT_I8 to a VT_I1.
 *
 * PARAMS
 *  llIn  [I] Source
 *  pcOut [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if the source value is invalid
 *           DISP_E_OVERFLOW, if the value will not fit in the destination
 */
HRESULT WINAPI VarI1FromI8(LONG64 llIn, signed char* pcOut)
{
  return _VarI1FromI8(llIn, pcOut);
}

/************************************************************************
 * VarI1FromUI8 (OLEAUT32.377)
 *
 * Convert a VT_UI8 to a VT_I1.
 *
 * PARAMS
 *  ullIn   [I] Source
 *  pcOut   [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if the source value is invalid
 *           DISP_E_OVERFLOW, if the value will not fit in the destination
 */
HRESULT WINAPI VarI1FromUI8(ULONG64 ullIn, signed char* pcOut)
{
  return _VarI1FromUI8(ullIn, pcOut);
}

/* UI1
 */

/************************************************************************
 * VarUI1FromI2 (OLEAUT32.130)
 *
 * Convert a VT_I2 to a VT_UI1.
 *
 * PARAMS
 *  sIn   [I] Source
 *  pbOut [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if the source value is invalid
 *           DISP_E_OVERFLOW, if the value will not fit in the destination
 */
HRESULT WINAPI VarUI1FromI2(SHORT sIn, BYTE* pbOut)
{
  return _VarUI1FromI2(sIn, pbOut);
}

/************************************************************************
 * VarUI1FromI4 (OLEAUT32.131)
 *
 * Convert a VT_I4 to a VT_UI1.
 *
 * PARAMS
 *  iIn   [I] Source
 *  pbOut [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if the source value is invalid
 *           DISP_E_OVERFLOW, if the value will not fit in the destination
 */
HRESULT WINAPI VarUI1FromI4(LONG iIn, BYTE* pbOut)
{
  return _VarUI1FromI4(iIn, pbOut);
}

/************************************************************************
 * VarUI1FromR4 (OLEAUT32.132)
 *
 * Convert a VT_R4 to a VT_UI1.
 *
 * PARAMS
 *  fltIn [I] Source
 *  pbOut [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if the source value is invalid
 *           DISP_E_OVERFLOW, if the value will not fit in the destination
 *           DISP_E_TYPEMISMATCH, if the type cannot be converted
 */
HRESULT WINAPI VarUI1FromR4(FLOAT fltIn, BYTE* pbOut)
{
  return VarUI1FromR8(fltIn, pbOut);
}

/************************************************************************
 * VarUI1FromR8 (OLEAUT32.133)
 *
 * Convert a VT_R8 to a VT_UI1.
 *
 * PARAMS
 *  dblIn [I] Source
 *  pbOut [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if the source value is invalid
 *           DISP_E_OVERFLOW, if the value will not fit in the destination
 *
 * NOTES
 *  See VarI8FromR8() for details concerning rounding.
 */
HRESULT WINAPI VarUI1FromR8(double dblIn, BYTE* pbOut)
{
  if (dblIn < -0.5 || dblIn > (double)UI1_MAX)
    return DISP_E_OVERFLOW;
  VARIANT_DutchRound(BYTE, dblIn, *pbOut);
  return S_OK;
}

/************************************************************************
 * VarUI1FromCy (OLEAUT32.134)
 *
 * Convert a VT_CY to a VT_UI1.
 *
 * PARAMS
 *  cyIn     [I] Source
 *  pbOut [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if the source value is invalid
 *           DISP_E_OVERFLOW, if the value will not fit in the destination
 *
 * NOTES
 *  Negative values >= -5000 will be converted to 0.
 */
HRESULT WINAPI VarUI1FromCy(CY cyIn, BYTE* pbOut)
{
  ULONG i = UI1_MAX + 1;

  VarUI4FromCy(cyIn, &i);
  return _VarUI1FromUI4(i, pbOut);
}

/************************************************************************
 * VarUI1FromDate (OLEAUT32.135)
 *
 * Convert a VT_DATE to a VT_UI1.
 *
 * PARAMS
 *  dateIn [I] Source
 *  pbOut  [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if the source value is invalid
 *           DISP_E_OVERFLOW, if the value will not fit in the destination
 */
HRESULT WINAPI VarUI1FromDate(DATE dateIn, BYTE* pbOut)
{
  return VarUI1FromR8(dateIn, pbOut);
}

/************************************************************************
 * VarUI1FromStr (OLEAUT32.136)
 *
 * Convert a VT_BSTR to a VT_UI1.
 *
 * PARAMS
 *  strIn   [I] Source
 *  lcid    [I] LCID for the conversion
 *  dwFlags [I] Flags controlling the conversion (VAR_ flags from "oleauto.h")
 *  pbOut   [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if the source value is invalid
 *           DISP_E_OVERFLOW, if the value will not fit in the destination
 *           DISP_E_TYPEMISMATCH, if the type cannot be converted
 */
HRESULT WINAPI VarUI1FromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, BYTE* pbOut)
{
  return VARIANT_NumberFromBstr(strIn, lcid, dwFlags, pbOut, VT_UI1);
}

/************************************************************************
 * VarUI1FromDisp (OLEAUT32.137)
 *
 * Convert a VT_DISPATCH to a VT_UI1.
 *
 * PARAMS
 *  pdispIn [I] Source
 *  lcid    [I] LCID for conversion
 *  pbOut   [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if the source value is invalid
 *           DISP_E_OVERFLOW, if the value will not fit in the destination
 *           DISP_E_TYPEMISMATCH, if the type cannot be converted
 */
HRESULT WINAPI VarUI1FromDisp(IDispatch* pdispIn, LCID lcid, BYTE* pbOut)
{
  return VARIANT_FromDisp(pdispIn, lcid, pbOut, VT_UI1, 0);
}

/************************************************************************
 * VarUI1FromBool (OLEAUT32.138)
 *
 * Convert a VT_BOOL to a VT_UI1.
 *
 * PARAMS
 *  boolIn [I] Source
 *  pbOut  [O] Destination
 *
 * RETURNS
 *  S_OK.
 */
HRESULT WINAPI VarUI1FromBool(VARIANT_BOOL boolIn, BYTE* pbOut)
{
  return _VarUI1FromBool(boolIn, pbOut);
}

/************************************************************************
 * VarUI1FromI1 (OLEAUT32.237)
 *
 * Convert a VT_I1 to a VT_UI1.
 *
 * PARAMS
 *  cIn   [I] Source
 *  pbOut [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if the source value is invalid
 *           DISP_E_OVERFLOW, if the value will not fit in the destination
 */
HRESULT WINAPI VarUI1FromI1(signed char cIn, BYTE* pbOut)
{
  return _VarUI1FromI1(cIn, pbOut);
}

/************************************************************************
 * VarUI1FromUI2 (OLEAUT32.238)
 *
 * Convert a VT_UI2 to a VT_UI1.
 *
 * PARAMS
 *  usIn  [I] Source
 *  pbOut [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if the source value is invalid
 *           DISP_E_OVERFLOW, if the value will not fit in the destination
 */
HRESULT WINAPI VarUI1FromUI2(USHORT usIn, BYTE* pbOut)
{
  return _VarUI1FromUI2(usIn, pbOut);
}

/************************************************************************
 * VarUI1FromUI4 (OLEAUT32.239)
 *
 * Convert a VT_UI4 to a VT_UI1.
 *
 * PARAMS
 *  ulIn  [I] Source
 *  pbOut [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if the source value is invalid
 *           DISP_E_OVERFLOW, if the value will not fit in the destination
 */
HRESULT WINAPI VarUI1FromUI4(ULONG ulIn, BYTE* pbOut)
{
  return _VarUI1FromUI4(ulIn, pbOut);
}

/************************************************************************
 * VarUI1FromDec (OLEAUT32.240)
 *
 * Convert a VT_DECIMAL to a VT_UI1.
 *
 * PARAMS
 *  pDecIn [I] Source
 *  pbOut  [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if the source value is invalid
 *           DISP_E_OVERFLOW, if the value will not fit in the destination
 */
HRESULT WINAPI VarUI1FromDec(DECIMAL *pdecIn, BYTE* pbOut)
{
  LONG64 i64;
  HRESULT hRet;

  hRet = VarI8FromDec(pdecIn, &i64);

  if (SUCCEEDED(hRet))
    hRet = _VarUI1FromI8(i64, pbOut);
  return hRet;
}

/************************************************************************
 * VarUI1FromI8 (OLEAUT32.372)
 *
 * Convert a VT_I8 to a VT_UI1.
 *
 * PARAMS
 *  llIn  [I] Source
 *  pbOut [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if the source value is invalid
 *           DISP_E_OVERFLOW, if the value will not fit in the destination
 */
HRESULT WINAPI VarUI1FromI8(LONG64 llIn, BYTE* pbOut)
{
  return _VarUI1FromI8(llIn, pbOut);
}

/************************************************************************
 * VarUI1FromUI8 (OLEAUT32.373)
 *
 * Convert a VT_UI8 to a VT_UI1.
 *
 * PARAMS
 *  ullIn   [I] Source
 *  pbOut   [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if the source value is invalid
 *           DISP_E_OVERFLOW, if the value will not fit in the destination
 */
HRESULT WINAPI VarUI1FromUI8(ULONG64 ullIn, BYTE* pbOut)
{
  return _VarUI1FromUI8(ullIn, pbOut);
}


/* I2
 */

/************************************************************************
 * VarI2FromUI1 (OLEAUT32.48)
 *
 * Convert a VT_UI2 to a VT_I2.
 *
 * PARAMS
 *  bIn     [I] Source
 *  psOut   [O] Destination
 *
 * RETURNS
 *  S_OK.
 */
HRESULT WINAPI VarI2FromUI1(BYTE bIn, SHORT* psOut)
{
  return _VarI2FromUI1(bIn, psOut);
}

/************************************************************************
 * VarI2FromI4 (OLEAUT32.49)
 *
 * Convert a VT_I4 to a VT_I2.
 *
 * PARAMS
 *  iIn     [I] Source
 *  psOut   [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
 */
HRESULT WINAPI VarI2FromI4(LONG iIn, SHORT* psOut)
{
  return _VarI2FromI4(iIn, psOut);
}

/************************************************************************
 * VarI2FromR4 (OLEAUT32.50)
 *
 * Convert a VT_R4 to a VT_I2.
 *
 * PARAMS
 *  fltIn   [I] Source
 *  psOut   [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
 */
HRESULT WINAPI VarI2FromR4(FLOAT fltIn, SHORT* psOut)
{
  return VarI2FromR8(fltIn, psOut);
}

/************************************************************************
 * VarI2FromR8 (OLEAUT32.51)
 *
 * Convert a VT_R8 to a VT_I2.
 *
 * PARAMS
 *  dblIn   [I] Source
 *  psOut   [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
 *
 * NOTES
 *  See VarI8FromR8() for details concerning rounding.
 */
HRESULT WINAPI VarI2FromR8(double dblIn, SHORT* psOut)
{
  if (dblIn < (double)I2_MIN || dblIn > (double)I2_MAX)
    return DISP_E_OVERFLOW;
  VARIANT_DutchRound(SHORT, dblIn, *psOut);
  return S_OK;
}

/************************************************************************
 * VarI2FromCy (OLEAUT32.52)
 *
 * Convert a VT_CY to a VT_I2.
 *
 * PARAMS
 *  cyIn    [I] Source
 *  psOut   [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
 */
HRESULT WINAPI VarI2FromCy(CY cyIn, SHORT* psOut)
{
  LONG i = I2_MAX + 1;

  VarI4FromCy(cyIn, &i);
  return _VarI2FromI4(i, psOut);
}

/************************************************************************
 * VarI2FromDate (OLEAUT32.53)
 *
 * Convert a VT_DATE to a VT_I2.
 *
 * PARAMS
 *  dateIn  [I] Source
 *  psOut   [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
 */
HRESULT WINAPI VarI2FromDate(DATE dateIn, SHORT* psOut)
{
  return VarI2FromR8(dateIn, psOut);
}

/************************************************************************
 * VarI2FromStr (OLEAUT32.54)
 *
 * Convert a VT_BSTR to a VT_I2.
 *
 * PARAMS
 *  strIn   [I] Source
 *  lcid    [I] LCID for the conversion
 *  dwFlags [I] Flags controlling the conversion (VAR_ flags from "oleauto.h")
 *  psOut   [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if any parameter is invalid
 *           DISP_E_OVERFLOW, if the value will not fit in the destination
 *           DISP_E_TYPEMISMATCH, if the type cannot be converted
 */
HRESULT WINAPI VarI2FromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, SHORT* psOut)
{
  return VARIANT_NumberFromBstr(strIn, lcid, dwFlags, psOut, VT_I2);
}

/************************************************************************
 * VarI2FromDisp (OLEAUT32.55)
 *
 * Convert a VT_DISPATCH to a VT_I2.
 *
 * PARAMS
 *  pdispIn  [I] Source
 *  lcid     [I] LCID for conversion
 *  psOut    [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if pdispIn is invalid,
 *           DISP_E_OVERFLOW, if the value will not fit in the destination,
 *           DISP_E_TYPEMISMATCH, if the type cannot be converted
 */
HRESULT WINAPI VarI2FromDisp(IDispatch* pdispIn, LCID lcid, SHORT* psOut)
{
  return VARIANT_FromDisp(pdispIn, lcid, psOut, VT_I2, 0);
}

/************************************************************************
 * VarI2FromBool (OLEAUT32.56)
 *
 * Convert a VT_BOOL to a VT_I2.
 *
 * PARAMS
 *  boolIn  [I] Source
 *  psOut   [O] Destination
 *
 * RETURNS
 *  S_OK.
 */
HRESULT WINAPI VarI2FromBool(VARIANT_BOOL boolIn, SHORT* psOut)
{
  return _VarI2FromBool(boolIn, psOut);
}

/************************************************************************
 * VarI2FromI1 (OLEAUT32.205)
 *
 * Convert a VT_I1 to a VT_I2.
 *
 * PARAMS
 *  cIn     [I] Source
 *  psOut   [O] Destination
 *
 * RETURNS
 *  S_OK.
 */
HRESULT WINAPI VarI2FromI1(signed char cIn, SHORT* psOut)
{
  return _VarI2FromI1(cIn, psOut);
}

/************************************************************************
 * VarI2FromUI2 (OLEAUT32.206)
 *
 * Convert a VT_UI2 to a VT_I2.
 *
 * PARAMS
 *  usIn    [I] Source
 *  psOut   [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
 */
HRESULT WINAPI VarI2FromUI2(USHORT usIn, SHORT* psOut)
{
  return _VarI2FromUI2(usIn, psOut);
}

/************************************************************************
 * VarI2FromUI4 (OLEAUT32.207)
 *
 * Convert a VT_UI4 to a VT_I2.
 *
 * PARAMS
 *  ulIn    [I] Source
 *  psOut   [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
 */
HRESULT WINAPI VarI2FromUI4(ULONG ulIn, SHORT* psOut)
{
  return _VarI2FromUI4(ulIn, psOut);
}

/************************************************************************
 * VarI2FromDec (OLEAUT32.208)
 *
 * Convert a VT_DECIMAL to a VT_I2.
 *
 * PARAMS
 *  pDecIn  [I] Source
 *  psOut   [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if the source value is invalid
 *           DISP_E_OVERFLOW, if the value will not fit in the destination
 */
HRESULT WINAPI VarI2FromDec(DECIMAL *pdecIn, SHORT* psOut)
{
  LONG64 i64;
  HRESULT hRet;

  hRet = VarI8FromDec(pdecIn, &i64);

  if (SUCCEEDED(hRet))
    hRet = _VarI2FromI8(i64, psOut);
  return hRet;
}

/************************************************************************
 * VarI2FromI8 (OLEAUT32.346)
 *
 * Convert a VT_I8 to a VT_I2.
 *
 * PARAMS
 *  llIn  [I] Source
 *  psOut [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
 */
HRESULT WINAPI VarI2FromI8(LONG64 llIn, SHORT* psOut)
{
  return _VarI2FromI8(llIn, psOut);
}

/************************************************************************
 * VarI2FromUI8 (OLEAUT32.347)
 *
 * Convert a VT_UI8 to a VT_I2.
 *
 * PARAMS
 *  ullIn [I] Source
 *  psOut [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
 */
HRESULT WINAPI VarI2FromUI8(ULONG64 ullIn, SHORT* psOut)
{
  return _VarI2FromUI8(ullIn, psOut);
}

/* UI2
 */

/************************************************************************
 * VarUI2FromUI1 (OLEAUT32.257)
 *
 * Convert a VT_UI1 to a VT_UI2.
 *
 * PARAMS
 *  bIn    [I] Source
 *  pusOut [O] Destination
 *
 * RETURNS
 *  S_OK.
 */
HRESULT WINAPI VarUI2FromUI1(BYTE bIn, USHORT* pusOut)
{
  return _VarUI2FromUI1(bIn, pusOut);
}

/************************************************************************
 * VarUI2FromI2 (OLEAUT32.258)
 *
 * Convert a VT_I2 to a VT_UI2.
 *
 * PARAMS
 *  sIn    [I] Source
 *  pusOut [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
 */
HRESULT WINAPI VarUI2FromI2(SHORT sIn, USHORT* pusOut)
{
  return _VarUI2FromI2(sIn, pusOut);
}

/************************************************************************
 * VarUI2FromI4 (OLEAUT32.259)
 *
 * Convert a VT_I4 to a VT_UI2.
 *
 * PARAMS
 *  iIn    [I] Source
 *  pusOut [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
 */
HRESULT WINAPI VarUI2FromI4(LONG iIn, USHORT* pusOut)
{
  return _VarUI2FromI4(iIn, pusOut);
}

/************************************************************************
 * VarUI2FromR4 (OLEAUT32.260)
 *
 * Convert a VT_R4 to a VT_UI2.
 *
 * PARAMS
 *  fltIn  [I] Source
 *  pusOut [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
 */
HRESULT WINAPI VarUI2FromR4(FLOAT fltIn, USHORT* pusOut)
{
  return VarUI2FromR8(fltIn, pusOut);
}

/************************************************************************
 * VarUI2FromR8 (OLEAUT32.261)
 *
 * Convert a VT_R8 to a VT_UI2.
 *
 * PARAMS
 *  dblIn  [I] Source
 *  pusOut [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
 *
 * NOTES
 *  See VarI8FromR8() for details concerning rounding.
 */
HRESULT WINAPI VarUI2FromR8(double dblIn, USHORT* pusOut)
{
  if (dblIn < -0.5 || dblIn > (double)UI2_MAX)
    return DISP_E_OVERFLOW;
  VARIANT_DutchRound(USHORT, dblIn, *pusOut);
  return S_OK;
}

/************************************************************************
 * VarUI2FromDate (OLEAUT32.262)
 *
 * Convert a VT_DATE to a VT_UI2.
 *
 * PARAMS
 *  dateIn [I] Source
 *  pusOut [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
 */
HRESULT WINAPI VarUI2FromDate(DATE dateIn, USHORT* pusOut)
{
  return VarUI2FromR8(dateIn, pusOut);
}

/************************************************************************
 * VarUI2FromCy (OLEAUT32.263)
 *
 * Convert a VT_CY to a VT_UI2.
 *
 * PARAMS
 *  cyIn   [I] Source
 *  pusOut [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
 *
 * NOTES
 *  Negative values >= -5000 will be converted to 0.
 */
HRESULT WINAPI VarUI2FromCy(CY cyIn, USHORT* pusOut)
{
  ULONG i = UI2_MAX + 1;

  VarUI4FromCy(cyIn, &i);
  return _VarUI2FromUI4(i, pusOut);
}

/************************************************************************
 * VarUI2FromStr (OLEAUT32.264)
 *
 * Convert a VT_BSTR to a VT_UI2.
 *
 * PARAMS
 *  strIn   [I] Source
 *  lcid    [I] LCID for the conversion
 *  dwFlags [I] Flags controlling the conversion (VAR_ flags from "oleauto.h")
 *  pusOut  [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
 *           DISP_E_TYPEMISMATCH, if the type cannot be converted
 */
HRESULT WINAPI VarUI2FromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, USHORT* pusOut)
{
  return VARIANT_NumberFromBstr(strIn, lcid, dwFlags, pusOut, VT_UI2);
}

/************************************************************************
 * VarUI2FromDisp (OLEAUT32.265)
 *
 * Convert a VT_DISPATCH to a VT_UI2.
 *
 * PARAMS
 *  pdispIn  [I] Source
 *  lcid     [I] LCID for conversion
 *  pusOut   [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if the source value is invalid
 *           DISP_E_OVERFLOW, if the value will not fit in the destination
 *           DISP_E_TYPEMISMATCH, if the type cannot be converted
 */
HRESULT WINAPI VarUI2FromDisp(IDispatch* pdispIn, LCID lcid, USHORT* pusOut)
{
  return VARIANT_FromDisp(pdispIn, lcid, pusOut, VT_UI2, 0);
}

/************************************************************************
 * VarUI2FromBool (OLEAUT32.266)
 *
 * Convert a VT_BOOL to a VT_UI2.
 *
 * PARAMS
 *  boolIn  [I] Source
 *  pusOut  [O] Destination
 *
 * RETURNS
 *  S_OK.
 */
HRESULT WINAPI VarUI2FromBool(VARIANT_BOOL boolIn, USHORT* pusOut)
{
  return _VarUI2FromBool(boolIn, pusOut);
}

/************************************************************************
 * VarUI2FromI1 (OLEAUT32.267)
 *
 * Convert a VT_I1 to a VT_UI2.
 *
 * PARAMS
 *  cIn    [I] Source
 *  pusOut [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
 */
HRESULT WINAPI VarUI2FromI1(signed char cIn, USHORT* pusOut)
{
  return _VarUI2FromI1(cIn, pusOut);
}

/************************************************************************
 * VarUI2FromUI4 (OLEAUT32.268)
 *
 * Convert a VT_UI4 to a VT_UI2.
 *
 * PARAMS
 *  ulIn   [I] Source
 *  pusOut [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
 */
HRESULT WINAPI VarUI2FromUI4(ULONG ulIn, USHORT* pusOut)
{
  return _VarUI2FromUI4(ulIn, pusOut);
}

/************************************************************************
 * VarUI2FromDec (OLEAUT32.269)
 *
 * Convert a VT_DECIMAL to a VT_UI2.
 *
 * PARAMS
 *  pDecIn  [I] Source
 *  pusOut  [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if the source value is invalid
 *           DISP_E_OVERFLOW, if the value will not fit in the destination
 */
HRESULT WINAPI VarUI2FromDec(DECIMAL *pdecIn, USHORT* pusOut)
{
  LONG64 i64;
  HRESULT hRet;

  hRet = VarI8FromDec(pdecIn, &i64);

  if (SUCCEEDED(hRet))
    hRet = _VarUI2FromI8(i64, pusOut);
  return hRet;
}

/************************************************************************
 * VarUI2FromI8 (OLEAUT32.378)
 *
 * Convert a VT_I8 to a VT_UI2.
 *
 * PARAMS
 *  llIn   [I] Source
 *  pusOut [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
 */
HRESULT WINAPI VarUI2FromI8(LONG64 llIn, USHORT* pusOut)
{
  return _VarUI2FromI8(llIn, pusOut);
}

/************************************************************************
 * VarUI2FromUI8 (OLEAUT32.379)
 *
 * Convert a VT_UI8 to a VT_UI2.
 *
 * PARAMS
 *  ullIn    [I] Source
 *  pusOut   [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
 */
HRESULT WINAPI VarUI2FromUI8(ULONG64 ullIn, USHORT* pusOut)
{
  return _VarUI2FromUI8(ullIn, pusOut);
}

/* I4
 */

/************************************************************************
 * VarI4FromUI1 (OLEAUT32.58)
 *
 * Convert a VT_UI1 to a VT_I4.
 *
 * PARAMS
 *  bIn     [I] Source
 *  piOut   [O] Destination
 *
 * RETURNS
 *  S_OK.
 */
HRESULT WINAPI VarI4FromUI1(BYTE bIn, LONG *piOut)
{
  return _VarI4FromUI1(bIn, piOut);
}

/************************************************************************
 * VarI4FromI2 (OLEAUT32.59)
 *
 * Convert a VT_I2 to a VT_I4.
 *
 * PARAMS
 *  sIn     [I] Source
 *  piOut   [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if the source value is invalid
 *           DISP_E_OVERFLOW, if the value will not fit in the destination
 */
HRESULT WINAPI VarI4FromI2(SHORT sIn, LONG *piOut)
{
  return _VarI4FromI2(sIn, piOut);
}

/************************************************************************
 * VarI4FromR4 (OLEAUT32.60)
 *
 * Convert a VT_R4 to a VT_I4.
 *
 * PARAMS
 *  fltIn   [I] Source
 *  piOut   [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
 */
HRESULT WINAPI VarI4FromR4(FLOAT fltIn, LONG *piOut)
{
  return VarI4FromR8(fltIn, piOut);
}

/************************************************************************
 * VarI4FromR8 (OLEAUT32.61)
 *
 * Convert a VT_R8 to a VT_I4.
 *
 * PARAMS
 *  dblIn   [I] Source
 *  piOut   [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
 *
 * NOTES
 *  See VarI8FromR8() for details concerning rounding.
 */
HRESULT WINAPI VarI4FromR8(double dblIn, LONG *piOut)
{
  if (dblIn < (double)I4_MIN || dblIn > (double)I4_MAX)
    return DISP_E_OVERFLOW;
  VARIANT_DutchRound(LONG, dblIn, *piOut);
  return S_OK;
}

/************************************************************************
 * VarI4FromCy (OLEAUT32.62)
 *
 * Convert a VT_CY to a VT_I4.
 *
 * PARAMS
 *  cyIn    [I] Source
 *  piOut   [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
 */
HRESULT WINAPI VarI4FromCy(CY cyIn, LONG *piOut)
{
  double d = cyIn.int64 / CY_MULTIPLIER_F;
  return VarI4FromR8(d, piOut);
}

/************************************************************************
 * VarI4FromDate (OLEAUT32.63)
 *
 * Convert a VT_DATE to a VT_I4.
 *
 * PARAMS
 *  dateIn  [I] Source
 *  piOut   [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
 */
HRESULT WINAPI VarI4FromDate(DATE dateIn, LONG *piOut)
{
  return VarI4FromR8(dateIn, piOut);
}

/************************************************************************
 * VarI4FromStr (OLEAUT32.64)
 *
 * Convert a VT_BSTR to a VT_I4.
 *
 * PARAMS
 *  strIn   [I] Source
 *  lcid    [I] LCID for the conversion
 *  dwFlags [I] Flags controlling the conversion (VAR_ flags from "oleauto.h")
 *  piOut   [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if any parameter is invalid
 *           DISP_E_OVERFLOW, if the value will not fit in the destination
 *           DISP_E_TYPEMISMATCH, if strIn cannot be converted
 */
HRESULT WINAPI VarI4FromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, LONG *piOut)
{
  return VARIANT_NumberFromBstr(strIn, lcid, dwFlags, piOut, VT_I4);
}

/************************************************************************
 * VarI4FromDisp (OLEAUT32.65)
 *
 * Convert a VT_DISPATCH to a VT_I4.
 *
 * PARAMS
 *  pdispIn  [I] Source
 *  lcid     [I] LCID for conversion
 *  piOut    [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if the source value is invalid
 *           DISP_E_OVERFLOW, if the value will not fit in the destination
 *           DISP_E_TYPEMISMATCH, if the type cannot be converted
 */
HRESULT WINAPI VarI4FromDisp(IDispatch* pdispIn, LCID lcid, LONG *piOut)
{
  return VARIANT_FromDisp(pdispIn, lcid, piOut, VT_I4, 0);
}

/************************************************************************
 * VarI4FromBool (OLEAUT32.66)
 *
 * Convert a VT_BOOL to a VT_I4.
 *
 * PARAMS
 *  boolIn  [I] Source
 *  piOut   [O] Destination
 *
 * RETURNS
 *  S_OK.
 */
HRESULT WINAPI VarI4FromBool(VARIANT_BOOL boolIn, LONG *piOut)
{
  return _VarI4FromBool(boolIn, piOut);
}

/************************************************************************
 * VarI4FromI1 (OLEAUT32.209)
 *
 * Convert a VT_I4 to a VT_I4.
 *
 * PARAMS
 *  cIn     [I] Source
 *  piOut   [O] Destination
 *
 * RETURNS
 *  S_OK.
 */
HRESULT WINAPI VarI4FromI1(signed char cIn, LONG *piOut)
{
  return _VarI4FromI1(cIn, piOut);
}

/************************************************************************
 * VarI4FromUI2 (OLEAUT32.210)
 *
 * Convert a VT_UI2 to a VT_I4.
 *
 * PARAMS
 *  usIn    [I] Source
 *  piOut   [O] Destination
 *
 * RETURNS
 *  S_OK.
 */
HRESULT WINAPI VarI4FromUI2(USHORT usIn, LONG *piOut)
{
  return _VarI4FromUI2(usIn, piOut);
}

/************************************************************************
 * VarI4FromUI4 (OLEAUT32.211)
 *
 * Convert a VT_UI4 to a VT_I4.
 *
 * PARAMS
 *  ulIn    [I] Source
 *  piOut   [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
 */
HRESULT WINAPI VarI4FromUI4(ULONG ulIn, LONG *piOut)
{
  return _VarI4FromUI4(ulIn, piOut);
}

/************************************************************************
 * VarI4FromDec (OLEAUT32.212)
 *
 * Convert a VT_DECIMAL to a VT_I4.
 *
 * PARAMS
 *  pDecIn  [I] Source
 *  piOut   [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if pdecIn is invalid
 *           DISP_E_OVERFLOW, if the value will not fit in the destination
 */
HRESULT WINAPI VarI4FromDec(DECIMAL *pdecIn, LONG *piOut)
{
  LONG64 i64;
  HRESULT hRet;

  hRet = VarI8FromDec(pdecIn, &i64);

  if (SUCCEEDED(hRet))
    hRet = _VarI4FromI8(i64, piOut);
  return hRet;
}

/************************************************************************
 * VarI4FromI8 (OLEAUT32.348)
 *
 * Convert a VT_I8 to a VT_I4.
 *
 * PARAMS
 *  llIn  [I] Source
 *  piOut [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
 */
HRESULT WINAPI VarI4FromI8(LONG64 llIn, LONG *piOut)
{
  return _VarI4FromI8(llIn, piOut);
}

/************************************************************************
 * VarI4FromUI8 (OLEAUT32.349)
 *
 * Convert a VT_UI8 to a VT_I4.
 *
 * PARAMS
 *  ullIn [I] Source
 *  piOut [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
 */
HRESULT WINAPI VarI4FromUI8(ULONG64 ullIn, LONG *piOut)
{
  return _VarI4FromUI8(ullIn, piOut);
}

/* UI4
 */

/************************************************************************
 * VarUI4FromUI1 (OLEAUT32.270)
 *
 * Convert a VT_UI1 to a VT_UI4.
 *
 * PARAMS
 *  bIn    [I] Source
 *  pulOut [O] Destination
 *
 * RETURNS
 *  S_OK.
 */
HRESULT WINAPI VarUI4FromUI1(BYTE bIn, ULONG *pulOut)
{
  return _VarUI4FromUI1(bIn, pulOut);
}

/************************************************************************
 * VarUI4FromI2 (OLEAUT32.271)
 *
 * Convert a VT_I2 to a VT_UI4.
 *
 * PARAMS
 *  sIn    [I] Source
 *  pulOut [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
 */
HRESULT WINAPI VarUI4FromI2(SHORT sIn, ULONG *pulOut)
{
  return _VarUI4FromI2(sIn, pulOut);
}

/************************************************************************
 * VarUI4FromI4 (OLEAUT32.272)
 *
 * Convert a VT_I4 to a VT_UI4.
 *
 * PARAMS
 *  iIn    [I] Source
 *  pulOut [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
 */
HRESULT WINAPI VarUI4FromI4(LONG iIn, ULONG *pulOut)
{
  return _VarUI4FromI4(iIn, pulOut);
}

/************************************************************************
 * VarUI4FromR4 (OLEAUT32.273)
 *
 * Convert a VT_R4 to a VT_UI4.
 *
 * PARAMS
 *  fltIn  [I] Source
 *  pulOut [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
 */
HRESULT WINAPI VarUI4FromR4(FLOAT fltIn, ULONG *pulOut)
{
  return VarUI4FromR8(fltIn, pulOut);
}

/************************************************************************
 * VarUI4FromR8 (OLEAUT32.274)
 *
 * Convert a VT_R8 to a VT_UI4.
 *
 * PARAMS
 *  dblIn  [I] Source
 *  pulOut [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
 *
 * NOTES
 *  See VarI8FromR8() for details concerning rounding.
 */
HRESULT WINAPI VarUI4FromR8(double dblIn, ULONG *pulOut)
{
  if (dblIn < -0.5 || dblIn > (double)UI4_MAX)
    return DISP_E_OVERFLOW;
  VARIANT_DutchRound(ULONG, dblIn, *pulOut);
  return S_OK;
}

/************************************************************************
 * VarUI4FromDate (OLEAUT32.275)
 *
 * Convert a VT_DATE to a VT_UI4.
 *
 * PARAMS
 *  dateIn [I] Source
 *  pulOut [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
 */
HRESULT WINAPI VarUI4FromDate(DATE dateIn, ULONG *pulOut)
{
  return VarUI4FromR8(dateIn, pulOut);
}

/************************************************************************
 * VarUI4FromCy (OLEAUT32.276)
 *
 * Convert a VT_CY to a VT_UI4.
 *
 * PARAMS
 *  cyIn   [I] Source
 *  pulOut [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
 */
HRESULT WINAPI VarUI4FromCy(CY cyIn, ULONG *pulOut)
{
  double d = cyIn.int64 / CY_MULTIPLIER_F;
  return VarUI4FromR8(d, pulOut);
}

/************************************************************************
 * VarUI4FromStr (OLEAUT32.277)
 *
 * Convert a VT_BSTR to a VT_UI4.
 *
 * PARAMS
 *  strIn   [I] Source
 *  lcid    [I] LCID for the conversion
 *  dwFlags [I] Flags controlling the conversion (VAR_ flags from "oleauto.h")
 *  pulOut  [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if any parameter is invalid
 *           DISP_E_OVERFLOW, if the value will not fit in the destination
 *           DISP_E_TYPEMISMATCH, if strIn cannot be converted
 */
HRESULT WINAPI VarUI4FromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, ULONG *pulOut)
{
  return VARIANT_NumberFromBstr(strIn, lcid, dwFlags, pulOut, VT_UI4);
}

/************************************************************************
 * VarUI4FromDisp (OLEAUT32.278)
 *
 * Convert a VT_DISPATCH to a VT_UI4.
 *
 * PARAMS
 *  pdispIn  [I] Source
 *  lcid     [I] LCID for conversion
 *  pulOut   [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if the source value is invalid
 *           DISP_E_OVERFLOW, if the value will not fit in the destination
 *           DISP_E_TYPEMISMATCH, if the type cannot be converted
 */
HRESULT WINAPI VarUI4FromDisp(IDispatch* pdispIn, LCID lcid, ULONG *pulOut)
{
  return VARIANT_FromDisp(pdispIn, lcid, pulOut, VT_UI4, 0);
}

/************************************************************************
 * VarUI4FromBool (OLEAUT32.279)
 *
 * Convert a VT_BOOL to a VT_UI4.
 *
 * PARAMS
 *  boolIn  [I] Source
 *  pulOut  [O] Destination
 *
 * RETURNS
 *  S_OK.
 */
HRESULT WINAPI VarUI4FromBool(VARIANT_BOOL boolIn, ULONG *pulOut)
{
  return _VarUI4FromBool(boolIn, pulOut);
}

/************************************************************************
 * VarUI4FromI1 (OLEAUT32.280)
 *
 * Convert a VT_I1 to a VT_UI4.
 *
 * PARAMS
 *  cIn    [I] Source
 *  pulOut [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
 */
HRESULT WINAPI VarUI4FromI1(signed char cIn, ULONG *pulOut)
{
  return _VarUI4FromI1(cIn, pulOut);
}

/************************************************************************
 * VarUI4FromUI2 (OLEAUT32.281)
 *
 * Convert a VT_UI2 to a VT_UI4.
 *
 * PARAMS
 *  usIn   [I] Source
 *  pulOut [O] Destination
 *
 * RETURNS
 *  S_OK.
 */
HRESULT WINAPI VarUI4FromUI2(USHORT usIn, ULONG *pulOut)
{
  return _VarUI4FromUI2(usIn, pulOut);
}

/************************************************************************
 * VarUI4FromDec (OLEAUT32.282)
 *
 * Convert a VT_DECIMAL to a VT_UI4.
 *
 * PARAMS
 *  pDecIn  [I] Source
 *  pulOut  [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if pdecIn is invalid
 *           DISP_E_OVERFLOW, if the value will not fit in the destination
 */
HRESULT WINAPI VarUI4FromDec(DECIMAL *pdecIn, ULONG *pulOut)
{
  LONG64 i64;
  HRESULT hRet;

  hRet = VarI8FromDec(pdecIn, &i64);

  if (SUCCEEDED(hRet))
    hRet = _VarUI4FromI8(i64, pulOut);
  return hRet;
}

/************************************************************************
 * VarUI4FromI8 (OLEAUT32.425)
 *
 * Convert a VT_I8 to a VT_UI4.
 *
 * PARAMS
 *  llIn   [I] Source
 *  pulOut [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
 */
HRESULT WINAPI VarUI4FromI8(LONG64 llIn, ULONG *pulOut)
{
  return _VarUI4FromI8(llIn, pulOut);
}

/************************************************************************
 * VarUI4FromUI8 (OLEAUT32.426)
 *
 * Convert a VT_UI8 to a VT_UI4.
 *
 * PARAMS
 *  ullIn    [I] Source
 *  pulOut   [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
 */
HRESULT WINAPI VarUI4FromUI8(ULONG64 ullIn, ULONG *pulOut)
{
  return _VarUI4FromUI8(ullIn, pulOut);
}

/* I8
 */

/************************************************************************
 * VarI8FromUI1 (OLEAUT32.333)
 *
 * Convert a VT_UI1 to a VT_I8.
 *
 * PARAMS
 *  bIn     [I] Source
 *  pi64Out [O] Destination
 *
 * RETURNS
 *  S_OK.
 */
HRESULT WINAPI VarI8FromUI1(BYTE bIn, LONG64* pi64Out)
{
  return _VarI8FromUI1(bIn, pi64Out);
}


/************************************************************************
 * VarI8FromI2 (OLEAUT32.334)
 *
 * Convert a VT_I2 to a VT_I8.
 *
 * PARAMS
 *  sIn     [I] Source
 *  pi64Out [O] Destination
 *
 * RETURNS
 *  S_OK.
 */
HRESULT WINAPI VarI8FromI2(SHORT sIn, LONG64* pi64Out)
{
  return _VarI8FromI2(sIn, pi64Out);
}

/************************************************************************
 * VarI8FromR4 (OLEAUT32.335)
 *
 * Convert a VT_R4 to a VT_I8.
 *
 * PARAMS
 *  fltIn   [I] Source
 *  pi64Out [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if the source value is invalid
 *           DISP_E_OVERFLOW, if the value will not fit in the destination
 */
HRESULT WINAPI VarI8FromR4(FLOAT fltIn, LONG64* pi64Out)
{
  return VarI8FromR8(fltIn, pi64Out);
}

/************************************************************************
 * VarI8FromR8 (OLEAUT32.336)
 *
 * Convert a VT_R8 to a VT_I8.
 *
 * PARAMS
 *  dblIn   [I] Source
 *  pi64Out [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if the source value is invalid
 *           DISP_E_OVERFLOW, if the value will not fit in the destination
 *
 * NOTES
 *  Only values that fit into 63 bits are accepted. Due to rounding issues,
 *  very high or low values will not be accurately converted.
 *
 *  Numbers are rounded using Dutch rounding, as follows:
 *
 *|  Fractional Part   Sign  Direction  Example
 *|  ---------------   ----  ---------  -------
 *|  < 0.5              +    Down        0.4 ->  0.0
 *|  < 0.5              -    Up         -0.4 ->  0.0
 *|  > 0.5              +    Up          0.6 ->  1.0
 *|  < 0.5              -    Up         -0.6 -> -1.0
 *|  = 0.5              +    Up/Down    Down if even, Up if odd
 *|  = 0.5              -    Up/Down    Up if even, Down if odd
 *
 *  This system is often used in supermarkets.
 */
HRESULT WINAPI VarI8FromR8(double dblIn, LONG64* pi64Out)
{
  if ( dblIn < -4611686018427387904.0 || dblIn >= 4611686018427387904.0)
    return DISP_E_OVERFLOW;
  VARIANT_DutchRound(LONG64, dblIn, *pi64Out);
  return S_OK;
}

/************************************************************************
 * VarI8FromCy (OLEAUT32.337)
 *
 * Convert a VT_CY to a VT_I8.
 *
 * PARAMS
 *  cyIn    [I] Source
 *  pi64Out [O] Destination
 *
 * RETURNS
 *  S_OK.
 *
 * NOTES
 *  All negative numbers are rounded down by 1, including those that are
 *  evenly divisible by 10000 (this is a Win32 bug that Wine mimics).
 *  Positive numbers are rounded using Dutch rounding: See VarI8FromR8()
 *  for details.
 */
HRESULT WINAPI VarI8FromCy(CY cyIn, LONG64* pi64Out)
{
  *pi64Out = cyIn.int64 / CY_MULTIPLIER;

  if (cyIn.int64 < 0)
    (*pi64Out)--; /* Mimic Win32 bug */
  else
  {
    cyIn.int64 -= *pi64Out * CY_MULTIPLIER; /* cyIn.s.Lo now holds fractional remainder */

    if (cyIn.s.Lo > CY_HALF || (cyIn.s.Lo == CY_HALF && (*pi64Out & 0x1)))
      (*pi64Out)++;
  }
  return S_OK;
}

/************************************************************************
 * VarI8FromDate (OLEAUT32.338)
 *
 * Convert a VT_DATE to a VT_I8.
 *
 * PARAMS
 *  dateIn  [I] Source
 *  pi64Out [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if the source value is invalid
 *           DISP_E_OVERFLOW, if the value will not fit in the destination
 *           DISP_E_TYPEMISMATCH, if the type cannot be converted
 */
HRESULT WINAPI VarI8FromDate(DATE dateIn, LONG64* pi64Out)
{
  return VarI8FromR8(dateIn, pi64Out);
}

/************************************************************************
 * VarI8FromStr (OLEAUT32.339)
 *
 * Convert a VT_BSTR to a VT_I8.
 *
 * PARAMS
 *  strIn   [I] Source
 *  lcid    [I] LCID for the conversion
 *  dwFlags [I] Flags controlling the conversion (VAR_ flags from "oleauto.h")
 *  pi64Out [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if the source value is invalid
 *           DISP_E_OVERFLOW, if the value will not fit in the destination
 *           DISP_E_TYPEMISMATCH, if the type cannot be converted
 */
HRESULT WINAPI VarI8FromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, LONG64* pi64Out)
{
  return VARIANT_NumberFromBstr(strIn, lcid, dwFlags, pi64Out, VT_I8);
}

/************************************************************************
 * VarI8FromDisp (OLEAUT32.340)
 *
 * Convert a VT_DISPATCH to a VT_I8.
 *
 * PARAMS
 *  pdispIn  [I] Source
 *  lcid     [I] LCID for conversion
 *  pi64Out  [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if the source value is invalid
 *           DISP_E_OVERFLOW, if the value will not fit in the destination
 *           DISP_E_TYPEMISMATCH, if the type cannot be converted
 */
HRESULT WINAPI VarI8FromDisp(IDispatch* pdispIn, LCID lcid, LONG64* pi64Out)
{
  return VARIANT_FromDisp(pdispIn, lcid, pi64Out, VT_I8, 0);
}

/************************************************************************
 * VarI8FromBool (OLEAUT32.341)
 *
 * Convert a VT_BOOL to a VT_I8.
 *
 * PARAMS
 *  boolIn  [I] Source
 *  pi64Out [O] Destination
 *
 * RETURNS
 *  S_OK.
 */
HRESULT WINAPI VarI8FromBool(VARIANT_BOOL boolIn, LONG64* pi64Out)
{
  return VarI8FromI2(boolIn, pi64Out);
}

/************************************************************************
 * VarI8FromI1 (OLEAUT32.342)
 *
 * Convert a VT_I1 to a VT_I8.
 *
 * PARAMS
 *  cIn     [I] Source
 *  pi64Out [O] Destination
 *
 * RETURNS
 *  S_OK.
 */
HRESULT WINAPI VarI8FromI1(signed char cIn, LONG64* pi64Out)
{
  return _VarI8FromI1(cIn, pi64Out);
}

/************************************************************************
 * VarI8FromUI2 (OLEAUT32.343)
 *
 * Convert a VT_UI2 to a VT_I8.
 *
 * PARAMS
 *  usIn    [I] Source
 *  pi64Out [O] Destination
 *
 * RETURNS
 *  S_OK.
 */
HRESULT WINAPI VarI8FromUI2(USHORT usIn, LONG64* pi64Out)
{
  return _VarI8FromUI2(usIn, pi64Out);
}

/************************************************************************
 * VarI8FromUI4 (OLEAUT32.344)
 *
 * Convert a VT_UI4 to a VT_I8.
 *
 * PARAMS
 *  ulIn    [I] Source
 *  pi64Out [O] Destination
 *
 * RETURNS
 *  S_OK.
 */
HRESULT WINAPI VarI8FromUI4(ULONG ulIn, LONG64* pi64Out)
{
  return _VarI8FromUI4(ulIn, pi64Out);
}

/************************************************************************
 * VarI8FromDec (OLEAUT32.345)
 *
 * Convert a VT_DECIMAL to a VT_I8.
 *
 * PARAMS
 *  pDecIn  [I] Source
 *  pi64Out [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if the source value is invalid
 *           DISP_E_OVERFLOW, if the value will not fit in the destination
 */
HRESULT WINAPI VarI8FromDec(DECIMAL *pdecIn, LONG64* pi64Out)
{
  if (!DEC_SCALE(pdecIn))
  {
    /* This decimal is just a 96 bit integer */
    if (DEC_SIGN(pdecIn) & ~DECIMAL_NEG)
      return E_INVALIDARG;

    if (DEC_HI32(pdecIn) || DEC_MID32(pdecIn) & 0x80000000)
      return DISP_E_OVERFLOW;

    if (DEC_SIGN(pdecIn))
      *pi64Out = -DEC_LO64(pdecIn);
    else
      *pi64Out = DEC_LO64(pdecIn);
    return S_OK;
  }
  else
  {
    /* Decimal contains a floating point number */
    HRESULT hRet;
    double dbl;

    hRet = VarR8FromDec(pdecIn, &dbl);
    if (SUCCEEDED(hRet))
      hRet = VarI8FromR8(dbl, pi64Out);
    return hRet;
  }
}

/************************************************************************
 * VarI8FromUI8 (OLEAUT32.427)
 *
 * Convert a VT_UI8 to a VT_I8.
 *
 * PARAMS
 *  ullIn   [I] Source
 *  pi64Out [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
 */
HRESULT WINAPI VarI8FromUI8(ULONG64 ullIn, LONG64* pi64Out)
{
  return _VarI8FromUI8(ullIn, pi64Out);
}

/* UI8
 */

/************************************************************************
 * VarUI8FromI8 (OLEAUT32.428)
 *
 * Convert a VT_I8 to a VT_UI8.
 *
 * PARAMS
 *  ulIn     [I] Source
 *  pui64Out [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
 */
HRESULT WINAPI VarUI8FromI8(LONG64 llIn, ULONG64* pui64Out)
{
  return _VarUI8FromI8(llIn, pui64Out);
}

/************************************************************************
 * VarUI8FromUI1 (OLEAUT32.429)
 *
 * Convert a VT_UI1 to a VT_UI8.
 *
 * PARAMS
 *  bIn      [I] Source
 *  pui64Out [O] Destination
 *
 * RETURNS
 *  S_OK.
 */
HRESULT WINAPI VarUI8FromUI1(BYTE bIn, ULONG64* pui64Out)
{
  return _VarUI8FromUI1(bIn, pui64Out);
}

/************************************************************************
 * VarUI8FromI2 (OLEAUT32.430)
 *
 * Convert a VT_I2 to a VT_UI8.
 *
 * PARAMS
 *  sIn      [I] Source
 *  pui64Out [O] Destination
 *
 * RETURNS
 *  S_OK.
 */
HRESULT WINAPI VarUI8FromI2(SHORT sIn, ULONG64* pui64Out)
{
  return _VarUI8FromI2(sIn, pui64Out);
}

/************************************************************************
 * VarUI8FromR4 (OLEAUT32.431)
 *
 * Convert a VT_R4 to a VT_UI8.
 *
 * PARAMS
 *  fltIn    [I] Source
 *  pui64Out [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
 */
HRESULT WINAPI VarUI8FromR4(FLOAT fltIn, ULONG64* pui64Out)
{
  return VarUI8FromR8(fltIn, pui64Out);
}

/************************************************************************
 * VarUI8FromR8 (OLEAUT32.432)
 *
 * Convert a VT_R8 to a VT_UI8.
 *
 * PARAMS
 *  dblIn    [I] Source
 *  pui64Out [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if the source value is invalid
 *           DISP_E_OVERFLOW, if the value will not fit in the destination
 *
 * NOTES
 *  See VarI8FromR8() for details concerning rounding.
 */
HRESULT WINAPI VarUI8FromR8(double dblIn, ULONG64* pui64Out)
{
  if (dblIn < -0.5 || dblIn > 1.844674407370955e19)
    return DISP_E_OVERFLOW;
  VARIANT_DutchRound(ULONG64, dblIn, *pui64Out);
  return S_OK;
}

/************************************************************************
 * VarUI8FromCy (OLEAUT32.433)
 *
 * Convert a VT_CY to a VT_UI8.
 *
 * PARAMS
 *  cyIn     [I] Source
 *  pui64Out [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if the source value is invalid
 *           DISP_E_OVERFLOW, if the value will not fit in the destination
 *
 * NOTES
 *  Negative values >= -5000 will be converted to 0.
 */
HRESULT WINAPI VarUI8FromCy(CY cyIn, ULONG64* pui64Out)
{
  if (cyIn.int64 < 0)
  {
    if (cyIn.int64 < -CY_HALF)
      return DISP_E_OVERFLOW;
    *pui64Out = 0;
  }
  else
  {
    *pui64Out = cyIn.int64 / CY_MULTIPLIER;

    cyIn.int64 -= *pui64Out * CY_MULTIPLIER; /* cyIn.s.Lo now holds fractional remainder */

    if (cyIn.s.Lo > CY_HALF || (cyIn.s.Lo == CY_HALF && (*pui64Out & 0x1)))
      (*pui64Out)++;
  }
  return S_OK;
}

/************************************************************************
 * VarUI8FromDate (OLEAUT32.434)
 *
 * Convert a VT_DATE to a VT_UI8.
 *
 * PARAMS
 *  dateIn   [I] Source
 *  pui64Out [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if the source value is invalid
 *           DISP_E_OVERFLOW, if the value will not fit in the destination
 *           DISP_E_TYPEMISMATCH, if the type cannot be converted
 */
HRESULT WINAPI VarUI8FromDate(DATE dateIn, ULONG64* pui64Out)
{
  return VarUI8FromR8(dateIn, pui64Out);
}

/************************************************************************
 * VarUI8FromStr (OLEAUT32.435)
 *
 * Convert a VT_BSTR to a VT_UI8.
 *
 * PARAMS
 *  strIn    [I] Source
 *  lcid     [I] LCID for the conversion
 *  dwFlags  [I] Flags controlling the conversion (VAR_ flags from "oleauto.h")
 *  pui64Out [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if the source value is invalid
 *           DISP_E_OVERFLOW, if the value will not fit in the destination
 *           DISP_E_TYPEMISMATCH, if the type cannot be converted
 */
HRESULT WINAPI VarUI8FromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, ULONG64* pui64Out)
{
  return VARIANT_NumberFromBstr(strIn, lcid, dwFlags, pui64Out, VT_UI8);
}

/************************************************************************
 * VarUI8FromDisp (OLEAUT32.436)
 *
 * Convert a VT_DISPATCH to a VT_UI8.
 *
 * PARAMS
 *  pdispIn   [I] Source
 *  lcid      [I] LCID for conversion
 *  pui64Out  [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if the source value is invalid
 *           DISP_E_OVERFLOW, if the value will not fit in the destination
 *           DISP_E_TYPEMISMATCH, if the type cannot be converted
 */
HRESULT WINAPI VarUI8FromDisp(IDispatch* pdispIn, LCID lcid, ULONG64* pui64Out)
{
  return VARIANT_FromDisp(pdispIn, lcid, pui64Out, VT_UI8, 0);
}

/************************************************************************
 * VarUI8FromBool (OLEAUT32.437)
 *
 * Convert a VT_BOOL to a VT_UI8.
 *
 * PARAMS
 *  boolIn   [I] Source
 *  pui64Out [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
 */
HRESULT WINAPI VarUI8FromBool(VARIANT_BOOL boolIn, ULONG64* pui64Out)
{
  return VarI8FromI2(boolIn, (LONG64 *)pui64Out);
}
/************************************************************************
 * VarUI8FromI1 (OLEAUT32.438)
 *
 * Convert a VT_I1 to a VT_UI8.
 *
 * PARAMS
 *  cIn      [I] Source
 *  pui64Out [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
 */
HRESULT WINAPI VarUI8FromI1(signed char cIn, ULONG64* pui64Out)
{
  return _VarUI8FromI1(cIn, pui64Out);
}

/************************************************************************
 * VarUI8FromUI2 (OLEAUT32.439)
 *
 * Convert a VT_UI2 to a VT_UI8.
 *
 * PARAMS
 *  usIn     [I] Source
 *  pui64Out [O] Destination
 *
 * RETURNS
 *  S_OK.
 */
HRESULT WINAPI VarUI8FromUI2(USHORT usIn, ULONG64* pui64Out)
{
  return _VarUI8FromUI2(usIn, pui64Out);
}

/************************************************************************
 * VarUI8FromUI4 (OLEAUT32.440)
 *
 * Convert a VT_UI4 to a VT_UI8.
 *
 * PARAMS
 *  ulIn     [I] Source
 *  pui64Out [O] Destination
 *
 * RETURNS
 *  S_OK.
 */
HRESULT WINAPI VarUI8FromUI4(ULONG ulIn, ULONG64* pui64Out)
{
  return _VarUI8FromUI4(ulIn, pui64Out);
}

/************************************************************************
 * VarUI8FromDec (OLEAUT32.441)
 *
 * Convert a VT_DECIMAL to a VT_UI8.
 *
 * PARAMS
 *  pDecIn   [I] Source
 *  pui64Out [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if the source value is invalid
 *           DISP_E_OVERFLOW, if the value will not fit in the destination
 *
 * NOTES
 *  Under native Win32, if the source value has a scale of 0, its sign is
 *  ignored, i.e. this function takes the absolute value rather than fail
 *  with DISP_E_OVERFLOW. This bug has been fixed in Wine's implementation
 *  (use VarAbs() on pDecIn first if you really want this behaviour).
 */
HRESULT WINAPI VarUI8FromDec(DECIMAL *pdecIn, ULONG64* pui64Out)
{
  if (!DEC_SCALE(pdecIn))
  {
    /* This decimal is just a 96 bit integer */
    if (DEC_SIGN(pdecIn) & ~DECIMAL_NEG)
      return E_INVALIDARG;

    if (DEC_HI32(pdecIn))
      return DISP_E_OVERFLOW;

    if (DEC_SIGN(pdecIn))
    {
      WARN("Sign would be ignored under Win32!\n");
      return DISP_E_OVERFLOW;
    }

    *pui64Out = DEC_LO64(pdecIn);
    return S_OK;
  }
  else
  {
    /* Decimal contains a floating point number */
    HRESULT hRet;
    double dbl;

    hRet = VarR8FromDec(pdecIn, &dbl);
    if (SUCCEEDED(hRet))
      hRet = VarUI8FromR8(dbl, pui64Out);
    return hRet;
  }
}

/* R4
 */

/************************************************************************
 * VarR4FromUI1 (OLEAUT32.68)
 *
 * Convert a VT_UI1 to a VT_R4.
 *
 * PARAMS
 *  bIn     [I] Source
 *  pFltOut [O] Destination
 *
 * RETURNS
 *  S_OK.
 */
HRESULT WINAPI VarR4FromUI1(BYTE bIn, float *pFltOut)
{
  return _VarR4FromUI1(bIn, pFltOut);
}

/************************************************************************
 * VarR4FromI2 (OLEAUT32.69)
 *
 * Convert a VT_I2 to a VT_R4.
 *
 * PARAMS
 *  sIn     [I] Source
 *  pFltOut [O] Destination
 *
 * RETURNS
 *  S_OK.
 */
HRESULT WINAPI VarR4FromI2(SHORT sIn, float *pFltOut)
{
  return _VarR4FromI2(sIn, pFltOut);
}

/************************************************************************
 * VarR4FromI4 (OLEAUT32.70)
 *
 * Convert a VT_I4 to a VT_R4.
 *
 * PARAMS
 *  sIn     [I] Source
 *  pFltOut [O] Destination
 *
 * RETURNS
 *  S_OK.
 */
HRESULT WINAPI VarR4FromI4(LONG lIn, float *pFltOut)
{
  return _VarR4FromI4(lIn, pFltOut);
}

/************************************************************************
 * VarR4FromR8 (OLEAUT32.71)
 *
 * Convert a VT_R8 to a VT_R4.
 *
 * PARAMS
 *  dblIn   [I] Source
 *  pFltOut [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: DISP_E_OVERFLOW, if the value will not fit in the destination.
 */
HRESULT WINAPI VarR4FromR8(double dblIn, float *pFltOut)
{
  double d = dblIn < 0.0 ? -dblIn : dblIn;
  if (d > R4_MAX) return DISP_E_OVERFLOW;
  *pFltOut = dblIn;
  return S_OK;
}

/************************************************************************
 * VarR4FromCy (OLEAUT32.72)
 *
 * Convert a VT_CY to a VT_R4.
 *
 * PARAMS
 *  cyIn    [I] Source
 *  pFltOut [O] Destination
 *
 * RETURNS
 *  S_OK.
 */
HRESULT WINAPI VarR4FromCy(CY cyIn, float *pFltOut)
{
  *pFltOut = (double)cyIn.int64 / CY_MULTIPLIER_F;
  return S_OK;
}

/************************************************************************
 * VarR4FromDate (OLEAUT32.73)
 *
 * Convert a VT_DATE to a VT_R4.
 *
 * PARAMS
 *  dateIn  [I] Source
 *  pFltOut [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: DISP_E_OVERFLOW, if the value will not fit in the destination.
 */
HRESULT WINAPI VarR4FromDate(DATE dateIn, float *pFltOut)
{
  return VarR4FromR8(dateIn, pFltOut);
}

/************************************************************************
 * VarR4FromStr (OLEAUT32.74)
 *
 * Convert a VT_BSTR to a VT_R4.
 *
 * PARAMS
 *  strIn   [I] Source
 *  lcid    [I] LCID for the conversion
 *  dwFlags [I] Flags controlling the conversion (VAR_ flags from "oleauto.h")
 *  pFltOut [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if strIn or pFltOut is invalid.
 *           DISP_E_TYPEMISMATCH, if the type cannot be converted
 */
HRESULT WINAPI VarR4FromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, float *pFltOut)
{
  return VARIANT_NumberFromBstr(strIn, lcid, dwFlags, pFltOut, VT_R4);
}

/************************************************************************
 * VarR4FromDisp (OLEAUT32.75)
 *
 * Convert a VT_DISPATCH to a VT_R4.
 *
 * PARAMS
 *  pdispIn  [I] Source
 *  lcid     [I] LCID for conversion
 *  pFltOut  [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if the source value is invalid
 *           DISP_E_OVERFLOW, if the value will not fit in the destination
 *           DISP_E_TYPEMISMATCH, if the type cannot be converted
 */
HRESULT WINAPI VarR4FromDisp(IDispatch* pdispIn, LCID lcid, float *pFltOut)
{
  return VARIANT_FromDisp(pdispIn, lcid, pFltOut, VT_R4, 0);
}

/************************************************************************
 * VarR4FromBool (OLEAUT32.76)
 *
 * Convert a VT_BOOL to a VT_R4.
 *
 * PARAMS
 *  boolIn  [I] Source
 *  pFltOut [O] Destination
 *
 * RETURNS
 *  S_OK.
 */
HRESULT WINAPI VarR4FromBool(VARIANT_BOOL boolIn, float *pFltOut)
{
  return VarR4FromI2(boolIn, pFltOut);
}

/************************************************************************
 * VarR4FromI1 (OLEAUT32.213)
 *
 * Convert a VT_I1 to a VT_R4.
 *
 * PARAMS
 *  cIn     [I] Source
 *  pFltOut [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if the source value is invalid
 *           DISP_E_OVERFLOW, if the value will not fit in the destination
 *           DISP_E_TYPEMISMATCH, if the type cannot be converted
 */
HRESULT WINAPI VarR4FromI1(signed char cIn, float *pFltOut)
{
  return _VarR4FromI1(cIn, pFltOut);
}

/************************************************************************
 * VarR4FromUI2 (OLEAUT32.214)
 *
 * Convert a VT_UI2 to a VT_R4.
 *
 * PARAMS
 *  usIn    [I] Source
 *  pFltOut [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if the source value is invalid
 *           DISP_E_OVERFLOW, if the value will not fit in the destination
 *           DISP_E_TYPEMISMATCH, if the type cannot be converted
 */
HRESULT WINAPI VarR4FromUI2(USHORT usIn, float *pFltOut)
{
  return _VarR4FromUI2(usIn, pFltOut);
}

/************************************************************************
 * VarR4FromUI4 (OLEAUT32.215)
 *
 * Convert a VT_UI4 to a VT_R4.
 *
 * PARAMS
 *  ulIn    [I] Source
 *  pFltOut [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if the source value is invalid
 *           DISP_E_OVERFLOW, if the value will not fit in the destination
 *           DISP_E_TYPEMISMATCH, if the type cannot be converted
 */
HRESULT WINAPI VarR4FromUI4(ULONG ulIn, float *pFltOut)
{
  return _VarR4FromUI4(ulIn, pFltOut);
}

/************************************************************************
 * VarR4FromDec (OLEAUT32.216)
 *
 * Convert a VT_DECIMAL to a VT_R4.
 *
 * PARAMS
 *  pDecIn  [I] Source
 *  pFltOut [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if the source value is invalid.
 */
HRESULT WINAPI VarR4FromDec(DECIMAL* pDecIn, float *pFltOut)
{
  BYTE scale = DEC_SCALE(pDecIn);
  int divisor = 1;
  double highPart;

  if (scale > DEC_MAX_SCALE || DEC_SIGN(pDecIn) & ~DECIMAL_NEG)
    return E_INVALIDARG;

  while (scale--)
    divisor *= 10;

  if (DEC_SIGN(pDecIn))
    divisor = -divisor;

  if (DEC_HI32(pDecIn))
  {
    highPart = (double)DEC_HI32(pDecIn) / (double)divisor;
    highPart *= 4294967296.0F;
    highPart *= 4294967296.0F;
  }
  else
    highPart = 0.0;

  *pFltOut = (double)DEC_LO64(pDecIn) / (double)divisor + highPart;
  return S_OK;
}

/************************************************************************
 * VarR4FromI8 (OLEAUT32.360)
 *
 * Convert a VT_I8 to a VT_R4.
 *
 * PARAMS
 *  ullIn   [I] Source
 *  pFltOut [O] Destination
 *
 * RETURNS
 *  S_OK.
 */
HRESULT WINAPI VarR4FromI8(LONG64 llIn, float *pFltOut)
{
  return _VarR4FromI8(llIn, pFltOut);
}

/************************************************************************
 * VarR4FromUI8 (OLEAUT32.361)
 *
 * Convert a VT_UI8 to a VT_R4.
 *
 * PARAMS
 *  ullIn   [I] Source
 *  pFltOut [O] Destination
 *
 * RETURNS
 *  S_OK.
 */
HRESULT WINAPI VarR4FromUI8(ULONG64 ullIn, float *pFltOut)
{
  return _VarR4FromUI8(ullIn, pFltOut);
}

/************************************************************************
 * VarR4CmpR8 (OLEAUT32.316)
 *
 * Compare a VT_R4 to a VT_R8.
 *
 * PARAMS
 *  fltLeft  [I] Source
 *  dblRight [I] Value to compare
 *
 * RETURNS
 *  VARCMP_LT, VARCMP_EQ or VARCMP_GT indicating that fltLeft is less than,
 *  equal to or greater than dblRight respectively.
 */
HRESULT WINAPI VarR4CmpR8(float fltLeft, double dblRight)
{
  if (fltLeft < dblRight)
    return VARCMP_LT;
  else if (fltLeft > dblRight)
    return VARCMP_GT;
  return VARCMP_EQ;
}

/* R8
 */

/************************************************************************
 * VarR8FromUI1 (OLEAUT32.78)
 *
 * Convert a VT_UI1 to a VT_R8.
 *
 * PARAMS
 *  bIn     [I] Source
 *  pDblOut [O] Destination
 *
 * RETURNS
 *  S_OK.
 */
HRESULT WINAPI VarR8FromUI1(BYTE bIn, double *pDblOut)
{
  return _VarR8FromUI1(bIn, pDblOut);
}

/************************************************************************
 * VarR8FromI2 (OLEAUT32.79)
 *
 * Convert a VT_I2 to a VT_R8.
 *
 * PARAMS
 *  sIn     [I] Source
 *  pDblOut [O] Destination
 *
 * RETURNS
 *  S_OK.
 */
HRESULT WINAPI VarR8FromI2(SHORT sIn, double *pDblOut)
{
  return _VarR8FromI2(sIn, pDblOut);
}

/************************************************************************
 * VarR8FromI4 (OLEAUT32.80)
 *
 * Convert a VT_I4 to a VT_R8.
 *
 * PARAMS
 *  sIn     [I] Source
 *  pDblOut [O] Destination
 *
 * RETURNS
 *  S_OK.
 */
HRESULT WINAPI VarR8FromI4(LONG lIn, double *pDblOut)
{
  return _VarR8FromI4(lIn, pDblOut);
}

/************************************************************************
 * VarR8FromR4 (OLEAUT32.81)
 *
 * Convert a VT_R4 to a VT_R8.
 *
 * PARAMS
 *  fltIn   [I] Source
 *  pDblOut [O] Destination
 *
 * RETURNS
 *  S_OK.
 */
HRESULT WINAPI VarR8FromR4(FLOAT fltIn, double *pDblOut)
{
  return _VarR8FromR4(fltIn, pDblOut);
}

/************************************************************************
 * VarR8FromCy (OLEAUT32.82)
 *
 * Convert a VT_CY to a VT_R8.
 *
 * PARAMS
 *  cyIn    [I] Source
 *  pDblOut [O] Destination
 *
 * RETURNS
 *  S_OK.
 */
HRESULT WINAPI VarR8FromCy(CY cyIn, double *pDblOut)
{
  return _VarR8FromCy(cyIn, pDblOut);
}

/************************************************************************
 * VarR8FromDate (OLEAUT32.83)
 *
 * Convert a VT_DATE to a VT_R8.
 *
 * PARAMS
 *  dateIn  [I] Source
 *  pDblOut [O] Destination
 *
 * RETURNS
 *  S_OK.
 */
HRESULT WINAPI VarR8FromDate(DATE dateIn, double *pDblOut)
{
  return _VarR8FromDate(dateIn, pDblOut);
}

/************************************************************************
 * VarR8FromStr (OLEAUT32.84)
 *
 * Convert a VT_BSTR to a VT_R8.
 *
 * PARAMS
 *  strIn   [I] Source
 *  lcid    [I] LCID for the conversion
 *  dwFlags [I] Flags controlling the conversion (VAR_ flags from "oleauto.h")
 *  pDblOut [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if strIn or pDblOut is invalid.
 *           DISP_E_TYPEMISMATCH, if the type cannot be converted
 */
HRESULT WINAPI VarR8FromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, double *pDblOut)
{
  return VARIANT_NumberFromBstr(strIn, lcid, dwFlags, pDblOut, VT_R8);
}

/************************************************************************
 * VarR8FromDisp (OLEAUT32.85)
 *
 * Convert a VT_DISPATCH to a VT_R8.
 *
 * PARAMS
 *  pdispIn  [I] Source
 *  lcid     [I] LCID for conversion
 *  pDblOut  [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if the source value is invalid
 *           DISP_E_OVERFLOW, if the value will not fit in the destination
 *           DISP_E_TYPEMISMATCH, if the type cannot be converted
 */
HRESULT WINAPI VarR8FromDisp(IDispatch* pdispIn, LCID lcid, double *pDblOut)
{
  return VARIANT_FromDisp(pdispIn, lcid, pDblOut, VT_R8, 0);
}

/************************************************************************
 * VarR8FromBool (OLEAUT32.86)
 *
 * Convert a VT_BOOL to a VT_R8.
 *
 * PARAMS
 *  boolIn  [I] Source
 *  pDblOut [O] Destination
 *
 * RETURNS
 *  S_OK.
 */
HRESULT WINAPI VarR8FromBool(VARIANT_BOOL boolIn, double *pDblOut)
{
  return VarR8FromI2(boolIn, pDblOut);
}

/************************************************************************
 * VarR8FromI1 (OLEAUT32.217)
 *
 * Convert a VT_I1 to a VT_R8.
 *
 * PARAMS
 *  cIn     [I] Source
 *  pDblOut [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if the source value is invalid
 *           DISP_E_OVERFLOW, if the value will not fit in the destination
 *           DISP_E_TYPEMISMATCH, if the type cannot be converted
 */
HRESULT WINAPI VarR8FromI1(signed char cIn, double *pDblOut)
{
  return _VarR8FromI1(cIn, pDblOut);
}

/************************************************************************
 * VarR8FromUI2 (OLEAUT32.218)
 *
 * Convert a VT_UI2 to a VT_R8.
 *
 * PARAMS
 *  usIn    [I] Source
 *  pDblOut [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if the source value is invalid
 *           DISP_E_OVERFLOW, if the value will not fit in the destination
 *           DISP_E_TYPEMISMATCH, if the type cannot be converted
 */
HRESULT WINAPI VarR8FromUI2(USHORT usIn, double *pDblOut)
{
  return _VarR8FromUI2(usIn, pDblOut);
}

/************************************************************************
 * VarR8FromUI4 (OLEAUT32.219)
 *
 * Convert a VT_UI4 to a VT_R8.
 *
 * PARAMS
 *  ulIn    [I] Source
 *  pDblOut [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if the source value is invalid
 *           DISP_E_OVERFLOW, if the value will not fit in the destination
 *           DISP_E_TYPEMISMATCH, if the type cannot be converted
 */
HRESULT WINAPI VarR8FromUI4(ULONG ulIn, double *pDblOut)
{
  return _VarR8FromUI4(ulIn, pDblOut);
}

/************************************************************************
 * VarR8FromDec (OLEAUT32.220)
 *
 * Convert a VT_DECIMAL to a VT_R8.
 *
 * PARAMS
 *  pDecIn  [I] Source
 *  pDblOut [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if the source value is invalid.
 */
HRESULT WINAPI VarR8FromDec(DECIMAL* pDecIn, double *pDblOut)
{
  BYTE scale = DEC_SCALE(pDecIn);
  double divisor = 1.0, highPart;

  if (scale > DEC_MAX_SCALE || DEC_SIGN(pDecIn) & ~DECIMAL_NEG)
    return E_INVALIDARG;

  while (scale--)
    divisor *= 10;

  if (DEC_SIGN(pDecIn))
    divisor = -divisor;

  if (DEC_HI32(pDecIn))
  {
    highPart = (double)DEC_HI32(pDecIn) / divisor;
    highPart *= 4294967296.0F;
    highPart *= 4294967296.0F;
  }
  else
    highPart = 0.0;

  *pDblOut = (double)DEC_LO64(pDecIn) / divisor + highPart;
  return S_OK;
}

/************************************************************************
 * VarR8FromI8 (OLEAUT32.362)
 *
 * Convert a VT_I8 to a VT_R8.
 *
 * PARAMS
 *  ullIn   [I] Source
 *  pDblOut [O] Destination
 *
 * RETURNS
 *  S_OK.
 */
HRESULT WINAPI VarR8FromI8(LONG64 llIn, double *pDblOut)
{
  return _VarR8FromI8(llIn, pDblOut);
}

/************************************************************************
 * VarR8FromUI8 (OLEAUT32.363)
 *
 * Convert a VT_UI8 to a VT_R8.
 *
 * PARAMS
 *  ullIn   [I] Source
 *  pDblOut [O] Destination
 *
 * RETURNS
 *  S_OK.
 */
HRESULT WINAPI VarR8FromUI8(ULONG64 ullIn, double *pDblOut)
{
  return _VarR8FromUI8(ullIn, pDblOut);
}

/************************************************************************
 * VarR8Pow (OLEAUT32.315)
 *
 * Raise a VT_R8 to a power.
 *
 * PARAMS
 *  dblLeft [I] Source
 *  dblPow  [I] Power to raise dblLeft by
 *  pDblOut [O] Destination
 *
 * RETURNS
 *  S_OK. pDblOut contains dblLeft to the power of dblRight.
 */
HRESULT WINAPI VarR8Pow(double dblLeft, double dblPow, double *pDblOut)
{
  *pDblOut = pow(dblLeft, dblPow);
  return S_OK;
}

/************************************************************************
 * VarR8Round (OLEAUT32.317)
 *
 * Round a VT_R8 to a given number of decimal points.
 *
 * PARAMS
 *  dblIn   [I] Source
 *  nDig    [I] Number of decimal points to round to
 *  pDblOut [O] Destination for rounded number
 *
 * RETURNS
 *  Success: S_OK. pDblOut is rounded to nDig digits.
 *  Failure: E_INVALIDARG, if cDecimals is less than 0.
 *
 * NOTES
 *  The native version of this function rounds using the internal
 *  binary representation of the number. Wine uses the dutch rounding
 *  convention, so therefore small differences can occur in the value returned.
 *  MSDN says that you should use your own rounding function if you want
 *  rounding to be predictable in your application.
 */
HRESULT WINAPI VarR8Round(double dblIn, int nDig, double *pDblOut)
{
  double scale, whole, fract;

  if (nDig < 0)
    return E_INVALIDARG;

  scale = pow(10.0, nDig);

  dblIn *= scale;
  whole = dblIn < 0 ? ceil(dblIn) : floor(dblIn);
  fract = dblIn - whole;

  if (fract > 0.5)
    dblIn = whole + 1.0;
  else if (fract == 0.5)
    dblIn = whole + fmod(whole, 2.0);
  else if (fract >= 0.0)
    dblIn = whole;
  else if (fract == -0.5)
    dblIn = whole - fmod(whole, 2.0);
  else if (fract > -0.5)
    dblIn = whole;
  else
    dblIn = whole - 1.0;

  *pDblOut = dblIn / scale;
  return S_OK;
}

/* CY
 */

/* Powers of 10 from 0..4 D.P. */
static const int CY_Divisors[5] = { CY_MULTIPLIER/10000, CY_MULTIPLIER/1000,
  CY_MULTIPLIER/100, CY_MULTIPLIER/10, CY_MULTIPLIER };

/************************************************************************
 * VarCyFromUI1 (OLEAUT32.98)
 *
 * Convert a VT_UI1 to a VT_CY.
 *
 * PARAMS
 *  bIn    [I] Source
 *  pCyOut [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if the source value is invalid
 *           DISP_E_OVERFLOW, if the value will not fit in the destination
 *           DISP_E_TYPEMISMATCH, if the type cannot be converted
 */
HRESULT WINAPI VarCyFromUI1(BYTE bIn, CY* pCyOut)
{
  return VarCyFromR8(bIn, pCyOut);
}

/************************************************************************
 * VarCyFromI2 (OLEAUT32.99)
 *
 * Convert a VT_I2 to a VT_CY.
 *
 * PARAMS
 *  sIn    [I] Source
 *  pCyOut [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if the source value is invalid
 *           DISP_E_OVERFLOW, if the value will not fit in the destination
 *           DISP_E_TYPEMISMATCH, if the type cannot be converted
 */
HRESULT WINAPI VarCyFromI2(SHORT sIn, CY* pCyOut)
{
  return VarCyFromR8(sIn, pCyOut);
}

/************************************************************************
 * VarCyFromI4 (OLEAUT32.100)
 *
 * Convert a VT_I4 to a VT_CY.
 *
 * PARAMS
 *  sIn    [I] Source
 *  pCyOut [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if the source value is invalid
 *           DISP_E_OVERFLOW, if the value will not fit in the destination
 *           DISP_E_TYPEMISMATCH, if the type cannot be converted
 */
HRESULT WINAPI VarCyFromI4(LONG lIn, CY* pCyOut)
{
  return VarCyFromR8(lIn, pCyOut);
}

/************************************************************************
 * VarCyFromR4 (OLEAUT32.101)
 *
 * Convert a VT_R4 to a VT_CY.
 *
 * PARAMS
 *  fltIn  [I] Source
 *  pCyOut [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if the source value is invalid
 *           DISP_E_OVERFLOW, if the value will not fit in the destination
 *           DISP_E_TYPEMISMATCH, if the type cannot be converted
 */
HRESULT WINAPI VarCyFromR4(FLOAT fltIn, CY* pCyOut)
{
  return VarCyFromR8(fltIn, pCyOut);
}

/************************************************************************
 * VarCyFromR8 (OLEAUT32.102)
 *
 * Convert a VT_R8 to a VT_CY.
 *
 * PARAMS
 *  dblIn  [I] Source
 *  pCyOut [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if the source value is invalid
 *           DISP_E_OVERFLOW, if the value will not fit in the destination
 *           DISP_E_TYPEMISMATCH, if the type cannot be converted
 */
HRESULT WINAPI VarCyFromR8(double dblIn, CY* pCyOut)
{
#if defined(__GNUC__) && defined(__i386__)
  /* This code gives identical results to Win32 on Intel.
   * Here we use fp exceptions to catch overflows when storing the value.
   */
  static const unsigned short r8_fpcontrol = 0x137f;
  static const double r8_multiplier = CY_MULTIPLIER_F;
  unsigned short old_fpcontrol, result_fpstatus;

  /* Clear exceptions, save the old fp state and load the new state */
  __asm__ __volatile__( "fnclex" );
  __asm__ __volatile__( "fstcw %0"   :   "=m" (old_fpcontrol) : );
  __asm__ __volatile__( "fldcw %0"   : : "m"  (r8_fpcontrol) );
  /* Perform the conversion. */
  __asm__ __volatile__( "fldl  %0"   : : "m"  (dblIn) );
  __asm__ __volatile__( "fmull %0"   : : "m"  (r8_multiplier) );
  __asm__ __volatile__( "fistpll %0" : : "m"  (*pCyOut) );
  /* Save the resulting fp state, load the old state and clear exceptions */
  __asm__ __volatile__( "fstsw %0"   :   "=m" (result_fpstatus) : );
  __asm__ __volatile__( "fnclex" );
  __asm__ __volatile__( "fldcw %0"   : : "m"  (old_fpcontrol) );

  if (result_fpstatus & 0x9) /* Overflow | Invalid */
    return DISP_E_OVERFLOW;
  return S_OK;
#else
  /* This version produces slightly different results for boundary cases */
  if (dblIn < -922337203685477.5807 || dblIn >= 922337203685477.5807)
    return DISP_E_OVERFLOW;
  dblIn *= CY_MULTIPLIER_F;
  VARIANT_DutchRound(LONG64, dblIn, pCyOut->int64);
#endif
  return S_OK;
}

/************************************************************************
 * VarCyFromDate (OLEAUT32.103)
 *
 * Convert a VT_DATE to a VT_CY.
 *
 * PARAMS
 *  dateIn [I] Source
 *  pCyOut [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if the source value is invalid
 *           DISP_E_OVERFLOW, if the value will not fit in the destination
 *           DISP_E_TYPEMISMATCH, if the type cannot be converted
 */
HRESULT WINAPI VarCyFromDate(DATE dateIn, CY* pCyOut)
{
  return VarCyFromR8(dateIn, pCyOut);
}

/************************************************************************
 * VarCyFromStr (OLEAUT32.104)
 *
 * Convert a VT_BSTR to a VT_CY.
 *
 * PARAMS
 *  strIn   [I] Source
 *  lcid    [I] LCID for the conversion
 *  dwFlags [I] Flags controlling the conversion (VAR_ flags from "oleauto.h")
 *  pCyOut  [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if the source value is invalid
 *           DISP_E_OVERFLOW, if the value will not fit in the destination
 *           DISP_E_TYPEMISMATCH, if the type cannot be converted
 */
HRESULT WINAPI VarCyFromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, CY* pCyOut)
{
  return VARIANT_NumberFromBstr(strIn, lcid, dwFlags, pCyOut, VT_CY);
}

/************************************************************************
 * VarCyFromDisp (OLEAUT32.105)
 *
 * Convert a VT_DISPATCH to a VT_CY.
 *
 * PARAMS
 *  pdispIn [I] Source
 *  lcid    [I] LCID for conversion
 *  pCyOut  [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if the source value is invalid
 *           DISP_E_OVERFLOW, if the value will not fit in the destination
 *           DISP_E_TYPEMISMATCH, if the type cannot be converted
 */
HRESULT WINAPI VarCyFromDisp(IDispatch* pdispIn, LCID lcid, CY* pCyOut)
{
  return VARIANT_FromDisp(pdispIn, lcid, pCyOut, VT_CY, 0);
}

/************************************************************************
 * VarCyFromBool (OLEAUT32.106)
 *
 * Convert a VT_BOOL to a VT_CY.
 *
 * PARAMS
 *  boolIn [I] Source
 *  pCyOut [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if the source value is invalid
 *           DISP_E_OVERFLOW, if the value will not fit in the destination
 *           DISP_E_TYPEMISMATCH, if the type cannot be converted
 *
 * NOTES
 *  While the sign of the boolean is stored in the currency, the value is
 *  converted to either 0 or 1.
 */
HRESULT WINAPI VarCyFromBool(VARIANT_BOOL boolIn, CY* pCyOut)
{
  return VarCyFromR8(boolIn, pCyOut);
}

/************************************************************************
 * VarCyFromI1 (OLEAUT32.225)
 *
 * Convert a VT_I1 to a VT_CY.
 *
 * PARAMS
 *  cIn    [I] Source
 *  pCyOut [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if the source value is invalid
 *           DISP_E_OVERFLOW, if the value will not fit in the destination
 *           DISP_E_TYPEMISMATCH, if the type cannot be converted
 */
HRESULT WINAPI VarCyFromI1(signed char cIn, CY* pCyOut)
{
  return VarCyFromR8(cIn, pCyOut);
}

/************************************************************************
 * VarCyFromUI2 (OLEAUT32.226)
 *
 * Convert a VT_UI2 to a VT_CY.
 *
 * PARAMS
 *  usIn   [I] Source
 *  pCyOut [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if the source value is invalid
 *           DISP_E_OVERFLOW, if the value will not fit in the destination
 *           DISP_E_TYPEMISMATCH, if the type cannot be converted
 */
HRESULT WINAPI VarCyFromUI2(USHORT usIn, CY* pCyOut)
{
  return VarCyFromR8(usIn, pCyOut);
}

/************************************************************************
 * VarCyFromUI4 (OLEAUT32.227)
 *
 * Convert a VT_UI4 to a VT_CY.
 *
 * PARAMS
 *  ulIn   [I] Source
 *  pCyOut [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if the source value is invalid
 *           DISP_E_OVERFLOW, if the value will not fit in the destination
 *           DISP_E_TYPEMISMATCH, if the type cannot be converted
 */
HRESULT WINAPI VarCyFromUI4(ULONG ulIn, CY* pCyOut)
{
  return VarCyFromR8(ulIn, pCyOut);
}

/************************************************************************
 * VarCyFromDec (OLEAUT32.228)
 *
 * Convert a VT_DECIMAL to a VT_CY.
 *
 * PARAMS
 *  pdecIn  [I] Source
 *  pCyOut  [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if the source value is invalid
 *           DISP_E_OVERFLOW, if the value will not fit in the destination
 *           DISP_E_TYPEMISMATCH, if the type cannot be converted
 */
HRESULT WINAPI VarCyFromDec(DECIMAL* pdecIn, CY* pCyOut)
{
  DECIMAL rounded;
  HRESULT hRet;

  hRet = VarDecRound(pdecIn, 4, &rounded);

  if (SUCCEEDED(hRet))
  {
    double d;

    if (DEC_HI32(&rounded))
      return DISP_E_OVERFLOW;

    /* Note: Without the casts this promotes to int64 which loses precision */
    d = (double)DEC_LO64(&rounded) / (double)CY_Divisors[DEC_SCALE(&rounded)];
    if (DEC_SIGN(&rounded))
      d = -d;
    return VarCyFromR8(d, pCyOut);
  }
  return hRet;
}

/************************************************************************
 * VarCyFromI8 (OLEAUT32.366)
 *
 * Convert a VT_I8 to a VT_CY.
 *
 * PARAMS
 *  ullIn  [I] Source
 *  pCyOut [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if the source value is invalid
 *           DISP_E_OVERFLOW, if the value will not fit in the destination
 *           DISP_E_TYPEMISMATCH, if the type cannot be converted
 */
HRESULT WINAPI VarCyFromI8(LONG64 llIn, CY* pCyOut)
{
  if (llIn <= (I8_MIN/CY_MULTIPLIER) || llIn >= (I8_MAX/CY_MULTIPLIER)) return DISP_E_OVERFLOW;
  pCyOut->int64 = llIn * CY_MULTIPLIER;
  return S_OK;
}

/************************************************************************
 * VarCyFromUI8 (OLEAUT32.375)
 *
 * Convert a VT_UI8 to a VT_CY.
 *
 * PARAMS
 *  ullIn  [I] Source
 *  pCyOut [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if the source value is invalid
 *           DISP_E_OVERFLOW, if the value will not fit in the destination
 *           DISP_E_TYPEMISMATCH, if the type cannot be converted
 */
HRESULT WINAPI VarCyFromUI8(ULONG64 ullIn, CY* pCyOut)
{
  return VarCyFromR8(ullIn, pCyOut);
}

/************************************************************************
 * VarCyAdd (OLEAUT32.299)
 *
 * Add one CY to another.
 *
 * PARAMS
 *  cyLeft  [I] Source
 *  cyRight [I] Value to add
 *  pCyOut  [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
 */
HRESULT WINAPI VarCyAdd(const CY cyLeft, const CY cyRight, CY* pCyOut)
{
  double l,r;
  _VarR8FromCy(cyLeft, &l);
  _VarR8FromCy(cyRight, &r);
  l = l + r;
  return VarCyFromR8(l, pCyOut);
}

/************************************************************************
 * VarCyMul (OLEAUT32.303)
 *
 * Multiply one CY by another.
 *
 * PARAMS
 *  cyLeft  [I] Source
 *  cyRight [I] Value to multiply by
 *  pCyOut  [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
 */
HRESULT WINAPI VarCyMul(const CY cyLeft, const CY cyRight, CY* pCyOut)
{
  double l,r;
  _VarR8FromCy(cyLeft, &l);
  _VarR8FromCy(cyRight, &r);
  l = l * r;
  return VarCyFromR8(l, pCyOut);
}

/************************************************************************
 * VarCyMulI4 (OLEAUT32.304)
 *
 * Multiply one CY by a VT_I4.
 *
 * PARAMS
 *  cyLeft  [I] Source
 *  lRight  [I] Value to multiply by
 *  pCyOut  [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
 */
HRESULT WINAPI VarCyMulI4(const CY cyLeft, LONG lRight, CY* pCyOut)
{
  double d;

  _VarR8FromCy(cyLeft, &d);
  d = d * lRight;
  return VarCyFromR8(d, pCyOut);
}

/************************************************************************
 * VarCySub (OLEAUT32.305)
 *
 * Subtract one CY from another.
 *
 * PARAMS
 *  cyLeft  [I] Source
 *  cyRight [I] Value to subtract
 *  pCyOut  [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
 */
HRESULT WINAPI VarCySub(const CY cyLeft, const CY cyRight, CY* pCyOut)
{
  double l,r;
  _VarR8FromCy(cyLeft, &l);
  _VarR8FromCy(cyRight, &r);
  l = l - r;
  return VarCyFromR8(l, pCyOut);
}

/************************************************************************
 * VarCyAbs (OLEAUT32.306)
 *
 * Convert a VT_CY into its absolute value.
 *
 * PARAMS
 *  cyIn   [I] Source
 *  pCyOut [O] Destination
 *
 * RETURNS
 *  Success: S_OK. pCyOut contains the absolute value.
 *  Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
 */
HRESULT WINAPI VarCyAbs(const CY cyIn, CY* pCyOut)
{
  if (cyIn.s.Hi == (int)0x80000000 && !cyIn.s.Lo)
    return DISP_E_OVERFLOW;

  pCyOut->int64 = cyIn.int64 < 0 ? -cyIn.int64 : cyIn.int64;
  return S_OK;
}

/************************************************************************
 * VarCyFix (OLEAUT32.307)
 *
 * Return the integer part of a VT_CY.
 *
 * PARAMS
 *  cyIn   [I] Source
 *  pCyOut [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
 *
 * NOTES
 *  - The difference between this function and VarCyInt() is that VarCyInt() rounds
 *    negative numbers away from 0, while this function rounds them towards zero.
 */
HRESULT WINAPI VarCyFix(const CY cyIn, CY* pCyOut)
{
  pCyOut->int64 = cyIn.int64 / CY_MULTIPLIER;
  pCyOut->int64 *= CY_MULTIPLIER;
  return S_OK;
}

/************************************************************************
 * VarCyInt (OLEAUT32.308)
 *
 * Return the integer part of a VT_CY.
 *
 * PARAMS
 *  cyIn   [I] Source
 *  pCyOut [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
 *
 * NOTES
 *  - The difference between this function and VarCyFix() is that VarCyFix() rounds
 *    negative numbers towards 0, while this function rounds them away from zero.
 */
HRESULT WINAPI VarCyInt(const CY cyIn, CY* pCyOut)
{
  pCyOut->int64 = cyIn.int64 / CY_MULTIPLIER;
  pCyOut->int64 *= CY_MULTIPLIER;

  if (cyIn.int64 < 0 && cyIn.int64 % CY_MULTIPLIER != 0)
  {
    pCyOut->int64 -= CY_MULTIPLIER;
  }
  return S_OK;
}

/************************************************************************
 * VarCyNeg (OLEAUT32.309)
 *
 * Change the sign of a VT_CY.
 *
 * PARAMS
 *  cyIn   [I] Source
 *  pCyOut [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
 */
HRESULT WINAPI VarCyNeg(const CY cyIn, CY* pCyOut)
{
  if (cyIn.s.Hi == (int)0x80000000 && !cyIn.s.Lo)
    return DISP_E_OVERFLOW;

  pCyOut->int64 = -cyIn.int64;
  return S_OK;
}

/************************************************************************
 * VarCyRound (OLEAUT32.310)
 *
 * Change the precision of a VT_CY.
 *
 * PARAMS
 *  cyIn      [I] Source
 *  cDecimals [I] New number of decimals to keep
 *  pCyOut    [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if cDecimals is less than 0.
 */
HRESULT WINAPI VarCyRound(const CY cyIn, int cDecimals, CY* pCyOut)
{
  if (cDecimals < 0)
    return E_INVALIDARG;

  if (cDecimals > 3)
  {
    /* Rounding to more precision than we have */
    *pCyOut = cyIn;
    return S_OK;
  }
  else
  {
    double d, div = CY_Divisors[cDecimals];

    _VarR8FromCy(cyIn, &d);
    d = d * div;
    VARIANT_DutchRound(LONGLONG, d, pCyOut->int64)
    d = (double)pCyOut->int64 / div * CY_MULTIPLIER_F;
    VARIANT_DutchRound(LONGLONG, d, pCyOut->int64)
    return S_OK;
  }
}

/************************************************************************
 * VarCyCmp (OLEAUT32.311)
 *
 * Compare two VT_CY values.
 *
 * PARAMS
 *  cyLeft  [I] Source
 *  cyRight [I] Value to compare
 *
 * RETURNS
 *  Success: VARCMP_LT, VARCMP_EQ or VARCMP_GT indicating that the value to
 *           compare is less, equal or greater than source respectively.
 *  Failure: DISP_E_OVERFLOW, if overflow occurs during the comparison
 */
HRESULT WINAPI VarCyCmp(const CY cyLeft, const CY cyRight)
{
  HRESULT hRet;
  CY result;

  /* Subtract right from left, and compare the result to 0 */
  hRet = VarCySub(cyLeft, cyRight, &result);

  if (SUCCEEDED(hRet))
  {
    if (result.int64 < 0)
      hRet = (HRESULT)VARCMP_LT;
    else if (result.int64 > 0)
      hRet = (HRESULT)VARCMP_GT;
    else
      hRet = (HRESULT)VARCMP_EQ;
  }
  return hRet;
}

/************************************************************************
 * VarCyCmpR8 (OLEAUT32.312)
 *
 * Compare a VT_CY to a double
 *
 * PARAMS
 *  cyLeft   [I] Currency Source
 *  dblRight [I] double to compare to cyLeft
 *
 * RETURNS
 *  Success: VARCMP_LT, VARCMP_EQ or VARCMP_GT indicating that dblRight is
 *           less than, equal to or greater than cyLeft respectively.
 *  Failure: DISP_E_OVERFLOW, if overflow occurs during the comparison
 */
HRESULT WINAPI VarCyCmpR8(const CY cyLeft, double dblRight)
{
  HRESULT hRet;
  CY cyRight;

  hRet = VarCyFromR8(dblRight, &cyRight);

  if (SUCCEEDED(hRet))
    hRet = VarCyCmp(cyLeft, cyRight);

  return hRet;
}

/************************************************************************
 * VarCyMulI8 (OLEAUT32.329)
 *
 * Multiply a VT_CY by a VT_I8.
 *
 * PARAMS
 *  cyLeft  [I] Source
 *  llRight [I] Value to multiply by
 *  pCyOut  [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
 */
HRESULT WINAPI VarCyMulI8(const CY cyLeft, LONG64 llRight, CY* pCyOut)
{
  double d;

  _VarR8FromCy(cyLeft, &d);
  d = d  * (double)llRight;
  return VarCyFromR8(d, pCyOut);
}

/* DECIMAL
 */

/************************************************************************
 * VarDecFromUI1 (OLEAUT32.190)
 *
 * Convert a VT_UI1 to a DECIMAL.
 *
 * PARAMS
 *  bIn     [I] Source
 *  pDecOut [O] Destination
 *
 * RETURNS
 *  S_OK.
 */
HRESULT WINAPI VarDecFromUI1(BYTE bIn, DECIMAL* pDecOut)
{
  return VarDecFromUI4(bIn, pDecOut);
}

/************************************************************************
 * VarDecFromI2 (OLEAUT32.191)
 *
 * Convert a VT_I2 to a DECIMAL.
 *
 * PARAMS
 *  sIn     [I] Source
 *  pDecOut [O] Destination
 *
 * RETURNS
 *  S_OK.
 */
HRESULT WINAPI VarDecFromI2(SHORT sIn, DECIMAL* pDecOut)
{
  return VarDecFromI4(sIn, pDecOut);
}

/************************************************************************
 * VarDecFromI4 (OLEAUT32.192)
 *
 * Convert a VT_I4 to a DECIMAL.
 *
 * PARAMS
 *  sIn     [I] Source
 *  pDecOut [O] Destination
 *
 * RETURNS
 *  S_OK.
 */
HRESULT WINAPI VarDecFromI4(LONG lIn, DECIMAL* pDecOut)
{
  DEC_HI32(pDecOut) = 0;
  DEC_MID32(pDecOut) = 0;

  if (lIn < 0)
  {
    DEC_SIGNSCALE(pDecOut) = SIGNSCALE(DECIMAL_NEG,0);
    DEC_LO32(pDecOut) = -lIn;
  }
  else
  {
    DEC_SIGNSCALE(pDecOut) = SIGNSCALE(DECIMAL_POS,0);
    DEC_LO32(pDecOut) = lIn;
  }
  return S_OK;
}

#define LOCALE_EN_US		(MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT))

/************************************************************************
 * VarDecFromR4 (OLEAUT32.193)
 *
 * Convert a VT_R4 to a DECIMAL.
 *
 * PARAMS
 *  fltIn   [I] Source
 *  pDecOut [O] Destination
 *
 * RETURNS
 *  S_OK.
 */
HRESULT WINAPI VarDecFromR4(FLOAT fltIn, DECIMAL* pDecOut)
{
  WCHAR buff[256];

  sprintfW( buff, szFloatFormatW, fltIn );
  return VarDecFromStr(buff, LOCALE_EN_US, 0, pDecOut);
}

/************************************************************************
 * VarDecFromR8 (OLEAUT32.194)
 *
 * Convert a VT_R8 to a DECIMAL.
 *
 * PARAMS
 *  dblIn   [I] Source
 *  pDecOut [O] Destination
 *
 * RETURNS
 *  S_OK.
 */
HRESULT WINAPI VarDecFromR8(double dblIn, DECIMAL* pDecOut)
{
  WCHAR buff[256];

  sprintfW( buff, szDoubleFormatW, dblIn );
  return VarDecFromStr(buff, LOCALE_EN_US, 0, pDecOut);
}

/************************************************************************
 * VarDecFromDate (OLEAUT32.195)
 *
 * Convert a VT_DATE to a DECIMAL.
 *
 * PARAMS
 *  dateIn  [I] Source
 *  pDecOut [O] Destination
 *
 * RETURNS
 *  S_OK.
 */
HRESULT WINAPI VarDecFromDate(DATE dateIn, DECIMAL* pDecOut)
{
  return VarDecFromR8(dateIn, pDecOut);
}

/************************************************************************
 * VarDecFromCy (OLEAUT32.196)
 *
 * Convert a VT_CY to a DECIMAL.
 *
 * PARAMS
 *  cyIn    [I] Source
 *  pDecOut [O] Destination
 *
 * RETURNS
 *  S_OK.
 */
HRESULT WINAPI VarDecFromCy(CY cyIn, DECIMAL* pDecOut)
{
  DEC_HI32(pDecOut) = 0;

  /* Note: This assumes 2s complement integer representation */
  if (cyIn.s.Hi & 0x80000000)
  {
    DEC_SIGNSCALE(pDecOut) = SIGNSCALE(DECIMAL_NEG,4);
    DEC_LO64(pDecOut) = -cyIn.int64;
  }
  else
  {
    DEC_SIGNSCALE(pDecOut) = SIGNSCALE(DECIMAL_POS,4);
    DEC_MID32(pDecOut) = cyIn.s.Hi;
    DEC_LO32(pDecOut) = cyIn.s.Lo;
  }
  return S_OK;
}

/************************************************************************
 * VarDecFromStr (OLEAUT32.197)
 *
 * Convert a VT_BSTR to a DECIMAL.
 *
 * PARAMS
 *  strIn   [I] Source
 *  lcid    [I] LCID for the conversion
 *  dwFlags [I] Flags controlling the conversion (VAR_ flags from "oleauto.h")
 *  pDecOut [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
 */
HRESULT WINAPI VarDecFromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, DECIMAL* pDecOut)
{
  return VARIANT_NumberFromBstr(strIn, lcid, dwFlags, pDecOut, VT_DECIMAL);
}

/************************************************************************
 * VarDecFromDisp (OLEAUT32.198)
 *
 * Convert a VT_DISPATCH to a DECIMAL.
 *
 * PARAMS
 *  pdispIn  [I] Source
 *  lcid     [I] LCID for conversion
 *  pDecOut  [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: DISP_E_TYPEMISMATCH, if the type cannot be converted
 */
HRESULT WINAPI VarDecFromDisp(IDispatch* pdispIn, LCID lcid, DECIMAL* pDecOut)
{
  return VARIANT_FromDisp(pdispIn, lcid, pDecOut, VT_DECIMAL, 0);
}

/************************************************************************
 * VarDecFromBool (OLEAUT32.199)
 *
 * Convert a VT_BOOL to a DECIMAL.
 *
 * PARAMS
 *  bIn     [I] Source
 *  pDecOut [O] Destination
 *
 * RETURNS
 *  S_OK.
 *
 * NOTES
 *  The value is converted to either 0 (if bIn is FALSE) or -1 (TRUE).
 */
HRESULT WINAPI VarDecFromBool(VARIANT_BOOL bIn, DECIMAL* pDecOut)
{
  DEC_HI32(pDecOut) = 0;
  DEC_MID32(pDecOut) = 0;
  if (bIn)
  {
    DEC_SIGNSCALE(pDecOut) = SIGNSCALE(DECIMAL_NEG,0);
    DEC_LO32(pDecOut) = 1;
  }
  else
  {
    DEC_SIGNSCALE(pDecOut) = SIGNSCALE(DECIMAL_POS,0);
    DEC_LO32(pDecOut) = 0;
  }
  return S_OK;
}

/************************************************************************
 * VarDecFromI1 (OLEAUT32.241)
 *
 * Convert a VT_I1 to a DECIMAL.
 *
 * PARAMS
 *  cIn     [I] Source
 *  pDecOut [O] Destination
 *
 * RETURNS
 *  S_OK.
 */
HRESULT WINAPI VarDecFromI1(signed char cIn, DECIMAL* pDecOut)
{
  return VarDecFromI4(cIn, pDecOut);
}

/************************************************************************
 * VarDecFromUI2 (OLEAUT32.242)
 *
 * Convert a VT_UI2 to a DECIMAL.
 *
 * PARAMS
 *  usIn    [I] Source
 *  pDecOut [O] Destination
 *
 * RETURNS
 *  S_OK.
 */
HRESULT WINAPI VarDecFromUI2(USHORT usIn, DECIMAL* pDecOut)
{
  return VarDecFromUI4(usIn, pDecOut);
}

/************************************************************************
 * VarDecFromUI4 (OLEAUT32.243)
 *
 * Convert a VT_UI4 to a DECIMAL.
 *
 * PARAMS
 *  ulIn    [I] Source
 *  pDecOut [O] Destination
 *
 * RETURNS
 *  S_OK.
 */
HRESULT WINAPI VarDecFromUI4(ULONG ulIn, DECIMAL* pDecOut)
{
  DEC_SIGNSCALE(pDecOut) = SIGNSCALE(DECIMAL_POS,0);
  DEC_HI32(pDecOut) = 0;
  DEC_MID32(pDecOut) = 0;
  DEC_LO32(pDecOut) = ulIn;
  return S_OK;
}

/************************************************************************
 * VarDecFromI8 (OLEAUT32.374)
 *
 * Convert a VT_I8 to a DECIMAL.
 *
 * PARAMS
 *  llIn    [I] Source
 *  pDecOut [O] Destination
 *
 * RETURNS
 *  S_OK.
 */
HRESULT WINAPI VarDecFromI8(LONG64 llIn, DECIMAL* pDecOut)
{
  PULARGE_INTEGER pLi = (PULARGE_INTEGER)&llIn;

  DEC_HI32(pDecOut) = 0;

  /* Note: This assumes 2s complement integer representation */
  if (pLi->u.HighPart & 0x80000000)
  {
    DEC_SIGNSCALE(pDecOut) = SIGNSCALE(DECIMAL_NEG,0);
    DEC_LO64(pDecOut) = -pLi->QuadPart;
  }
  else
  {
    DEC_SIGNSCALE(pDecOut) = SIGNSCALE(DECIMAL_POS,0);
    DEC_MID32(pDecOut) = pLi->u.HighPart;
    DEC_LO32(pDecOut) = pLi->u.LowPart;
  }
  return S_OK;
}

/************************************************************************
 * VarDecFromUI8 (OLEAUT32.375)
 *
 * Convert a VT_UI8 to a DECIMAL.
 *
 * PARAMS
 *  ullIn   [I] Source
 *  pDecOut [O] Destination
 *
 * RETURNS
 *  S_OK.
 */
HRESULT WINAPI VarDecFromUI8(ULONG64 ullIn, DECIMAL* pDecOut)
{
  DEC_SIGNSCALE(pDecOut) = SIGNSCALE(DECIMAL_POS,0);
  DEC_HI32(pDecOut) = 0;
  DEC_LO64(pDecOut) = ullIn;
  return S_OK;
}

/* Make two DECIMALS the same scale; used by math functions below */
static HRESULT VARIANT_DecScale(const DECIMAL** ppDecLeft,
                                const DECIMAL** ppDecRight,
                                DECIMAL* pDecOut)
{
  static DECIMAL scaleFactor;
  DECIMAL decTemp;
  int scaleAmount, i;
  HRESULT hRet = S_OK;

  if (DEC_SIGN(*ppDecLeft) & ~DECIMAL_NEG || DEC_SIGN(*ppDecRight) & ~DECIMAL_NEG)
    return E_INVALIDARG;

  DEC_LO32(&scaleFactor) = 10;

  i = scaleAmount = DEC_SCALE(*ppDecLeft) - DEC_SCALE(*ppDecRight);

  if (!scaleAmount)
    return S_OK; /* Same scale */

  if (scaleAmount > 0)
  {
    decTemp = *(*ppDecRight); /* Left is bigger - scale the right hand side */
    *ppDecRight = pDecOut;
  }
  else
  {
    decTemp = *(*ppDecLeft); /* Right is bigger - scale the left hand side */
    *ppDecLeft = pDecOut;
    i = scaleAmount = -scaleAmount;
  }

  if (DEC_SCALE(&decTemp) + scaleAmount > DEC_MAX_SCALE)
    return DISP_E_OVERFLOW; /* Can't scale up */

  /* Multiply up the value to be scaled by the correct amount */
  while (SUCCEEDED(hRet) && i--)
  {
    /* Note we are multiplying by a value with a scale of 0, so we don't recurse */
    hRet = VarDecMul(&decTemp, &scaleFactor, pDecOut);
    decTemp = *pDecOut;
  }
  DEC_SCALE(pDecOut) += scaleAmount; /* Set the new scale */
  return hRet;
}

/* Add two unsigned 32 bit values with overflow */
static ULONG VARIANT_Add(ULONG ulLeft, ULONG ulRight, ULONG* pulHigh)
{
  ULARGE_INTEGER ul64;

  ul64.QuadPart = (ULONG64)ulLeft + (ULONG64)ulRight + (ULONG64)*pulHigh;
  *pulHigh = ul64.u.HighPart;
  return ul64.u.LowPart;
}

/* Subtract two unsigned 32 bit values with underflow */
static ULONG VARIANT_Sub(ULONG ulLeft, ULONG ulRight, ULONG* pulHigh)
{
  int invert = 0;
  ULARGE_INTEGER ul64;

  ul64.QuadPart = (LONG64)ulLeft - (ULONG64)ulRight;
  if (ulLeft < ulRight)
    invert = 1;

  if (ul64.QuadPart > (ULONG64)*pulHigh)
    ul64.QuadPart -= (ULONG64)*pulHigh;
  else
  {
    ul64.QuadPart -= (ULONG64)*pulHigh;
    invert = 1;
  }
  if (invert)
    ul64.u.HighPart = -ul64.u.HighPart ;

  *pulHigh = ul64.u.HighPart;
  return ul64.u.LowPart;
}

/* Multiply two unsigned 32 bit values with overflow */
static ULONG VARIANT_Mul(ULONG ulLeft, ULONG ulRight, ULONG* pulHigh)
{
  ULARGE_INTEGER ul64;

  ul64.QuadPart = (ULONG64)ulLeft * (ULONG64)ulRight + (ULONG64)*pulHigh;
  *pulHigh = ul64.u.HighPart;
  return ul64.u.LowPart;
}

/* Compare two decimals that have the same scale */
static inline int VARIANT_DecCmp(const DECIMAL *pDecLeft, const DECIMAL *pDecRight)
{
  if ( DEC_HI32(pDecLeft) < DEC_HI32(pDecRight) ||
      (DEC_HI32(pDecLeft) <= DEC_HI32(pDecRight) && DEC_LO64(pDecLeft) < DEC_LO64(pDecRight)))
    return -1;
  else if (DEC_HI32(pDecLeft) == DEC_HI32(pDecRight) && DEC_LO64(pDecLeft) == DEC_LO64(pDecRight))
    return 0;
  return 1;
}

/************************************************************************
 * VarDecAdd (OLEAUT32.177)
 *
 * Add one DECIMAL to another.
 *
 * PARAMS
 *  pDecLeft  [I] Source
 *  pDecRight [I] Value to add
 *  pDecOut   [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
 */
HRESULT WINAPI VarDecAdd(const DECIMAL* pDecLeft, const DECIMAL* pDecRight, DECIMAL* pDecOut)
{
  HRESULT hRet;
  DECIMAL scaled;

  hRet = VARIANT_DecScale(&pDecLeft, &pDecRight, &scaled);

  if (SUCCEEDED(hRet))
  {
    /* Our decimals now have the same scale, we can add them as 96 bit integers */
    ULONG overflow = 0;
    BYTE sign = DECIMAL_POS;

    /* Correct for the sign of the result */
    if (DEC_SIGN(pDecLeft) && DEC_SIGN(pDecRight))
    {
      /* -x + -y : Negative */
      sign = DECIMAL_NEG;
      goto VarDecAdd_AsPositive;
    }
    else if (DEC_SIGN(pDecLeft) && !DEC_SIGN(pDecRight))
    {
      int cmp = VARIANT_DecCmp(pDecLeft, pDecRight);

      /* -x + y : Negative if x > y */
      if (cmp > 0)
      {
        sign = DECIMAL_NEG;
VarDecAdd_AsNegative:
        DEC_LO32(pDecOut)  = VARIANT_Sub(DEC_LO32(pDecLeft),  DEC_LO32(pDecRight),  &overflow);
        DEC_MID32(pDecOut) = VARIANT_Sub(DEC_MID32(pDecLeft), DEC_MID32(pDecRight), &overflow);
        DEC_HI32(pDecOut)  = VARIANT_Sub(DEC_HI32(pDecLeft),  DEC_HI32(pDecRight),  &overflow);
      }
      else
      {
VarDecAdd_AsInvertedNegative:
        DEC_LO32(pDecOut)  = VARIANT_Sub(DEC_LO32(pDecRight),  DEC_LO32(pDecLeft),  &overflow);
        DEC_MID32(pDecOut) = VARIANT_Sub(DEC_MID32(pDecRight), DEC_MID32(pDecLeft), &overflow);
        DEC_HI32(pDecOut)  = VARIANT_Sub(DEC_HI32(pDecRight),  DEC_HI32(pDecLeft),  &overflow);
      }
    }
    else if (!DEC_SIGN(pDecLeft) && DEC_SIGN(pDecRight))
    {
      int cmp = VARIANT_DecCmp(pDecLeft, pDecRight);

      /* x + -y : Negative if x <= y */
      if (cmp <= 0)
      {
        sign = DECIMAL_NEG;
        goto VarDecAdd_AsInvertedNegative;
      }
      goto VarDecAdd_AsNegative;
    }
    else
    {
      /* x + y : Positive */
VarDecAdd_AsPositive:
      DEC_LO32(pDecOut)  = VARIANT_Add(DEC_LO32(pDecLeft),  DEC_LO32(pDecRight),  &overflow);
      DEC_MID32(pDecOut) = VARIANT_Add(DEC_MID32(pDecLeft), DEC_MID32(pDecRight), &overflow);
      DEC_HI32(pDecOut)  = VARIANT_Add(DEC_HI32(pDecLeft),  DEC_HI32(pDecRight),  &overflow);
    }

    if (overflow)
      return DISP_E_OVERFLOW; /* overflowed */

    DEC_SCALE(pDecOut) = DEC_SCALE(pDecLeft);
    DEC_SIGN(pDecOut) = sign;
  }
  return hRet;
}

/* internal representation of the value stored in a DECIMAL. The bytes are
   stored from LSB at index 0 to MSB at index 11
 */
typedef struct DECIMAL_internal
{
    DWORD bitsnum[3];  /* 96 significant bits, unsigned */
    unsigned char scale;      /* number scaled * 10 ^ -(scale) */
    unsigned int  sign : 1;   /* 0 - positive, 1 - negative */
} VARIANT_DI;

/* translate from external DECIMAL format into an internal representation */
static void VARIANT_DIFromDec(const DECIMAL * from, VARIANT_DI * to)
{
    to->scale = DEC_SCALE(from);
    to->sign = DEC_SIGN(from) ? 1 : 0;

    to->bitsnum[0] = DEC_LO32(from);
    to->bitsnum[1] = DEC_MID32(from);
    to->bitsnum[2] = DEC_HI32(from);
}

static void VARIANT_DecFromDI(VARIANT_DI * from, DECIMAL * to)
{
    if (from->sign) {
        DEC_SIGNSCALE(to) = SIGNSCALE(DECIMAL_NEG, from->scale);
    } else {
        DEC_SIGNSCALE(to) = SIGNSCALE(DECIMAL_POS, from->scale);
    }

    DEC_LO32(to) = from->bitsnum[0];
    DEC_MID32(to) = from->bitsnum[1];
    DEC_HI32(to) = from->bitsnum[2];
}

/* clear an internal representation of a DECIMAL */
static void VARIANT_DI_clear(VARIANT_DI * i)
{
    memset(i, 0, sizeof(VARIANT_DI));
}

/* divide the (unsigned) number stored in p (LSB) by a byte value (<= 0xff). Any nonzero
   size is supported. The value in p is replaced by the quotient of the division, and
   the remainder is returned as a result. This routine is most often used with a divisor
   of 10 in order to scale up numbers, and in the DECIMAL->string conversion.
 */
static unsigned char VARIANT_int_divbychar(DWORD * p, unsigned int n, unsigned char divisor)
{
    if (divisor == 0) {
        /* division by 0 */
        return 0xFF;
    } else if (divisor == 1) {
        /* dividend remains unchanged */
        return 0;
    } else {
        unsigned char remainder = 0;
        ULONGLONG iTempDividend;
        signed int i;
        
        for (i = n - 1; i >= 0 && !p[i]; i--);  /* skip leading zeros */
        for (; i >= 0; i--) {
            iTempDividend = ((ULONGLONG)remainder << 32) + p[i];
            remainder = iTempDividend % divisor;
            p[i] = iTempDividend / divisor;
        }
        
        return remainder;
    }
}

/* check to test if encoded number is a zero. Returns 1 if zero, 0 for nonzero */
static int VARIANT_int_iszero(DWORD * p, unsigned int n)
{
    for (; n > 0; n--) if (*p++ != 0) return 0;
    return 1;
}

/* multiply two DECIMALS, without changing either one, and place result in third
   parameter. Result is normalized when scale is > 0. Attempts to remove significant
   digits when scale > 0 in order to fit an overflowing result. Final overflow
   flag is returned.
 */
static int VARIANT_DI_mul(VARIANT_DI * a, VARIANT_DI * b, VARIANT_DI * result)
{
    int r_overflow = 0;
    DWORD running[6];
    signed int mulstart;

    VARIANT_DI_clear(result);
    result->sign = (a->sign ^ b->sign) ? 1 : 0;

    /* Multiply 128-bit operands into a (max) 256-bit result. The scale
       of the result is formed by adding the scales of the operands.
     */
    result->scale = a->scale + b->scale;
    memset(running, 0, sizeof(running));

    /* count number of leading zero-bytes in operand A */
    for (mulstart = sizeof(a->bitsnum)/sizeof(DWORD) - 1; mulstart >= 0 && !a->bitsnum[mulstart]; mulstart--);
    if (mulstart < 0) {
        /* result is 0, because operand A is 0 */
        result->scale = 0;
        result->sign = 0;
    } else {
        unsigned char remainder = 0;
        int iA;        

        /* perform actual multiplication */
        for (iA = 0; iA <= mulstart; iA++) {
            ULONG iOverflowMul;
            int iB;
            
            for (iOverflowMul = 0, iB = 0; iB < sizeof(b->bitsnum)/sizeof(DWORD); iB++) {
                ULONG iRV;
                int iR;
                
                iRV = VARIANT_Mul(b->bitsnum[iB], a->bitsnum[iA], &iOverflowMul);
                iR = iA + iB;
                do {
                    running[iR] = VARIANT_Add(running[iR], 0, &iRV);
                    iR++;
                } while (iRV);
            }
        }

/* Too bad - native oleaut does not do this, so we should not either */
#if 0
        /* While the result is divisible by 10, and the scale > 0, divide by 10.
           This operation should not lose significant digits, and gives an
           opportunity to reduce the possibility of overflows in future
           operations issued by the application.
         */
        while (result->scale > 0) {
            memcpy(quotient, running, sizeof(quotient));
            remainder = VARIANT_int_divbychar(quotient, sizeof(quotient) / sizeof(DWORD), 10);
            if (remainder > 0) break;
            memcpy(running, quotient, sizeof(quotient));
            result->scale--;
        }
#endif
        /* While the 256-bit result overflows, and the scale > 0, divide by 10.
           This operation *will* lose significant digits of the result because
           all the factors of 10 were consumed by the previous operation.
        */
        while (result->scale > 0 && !VARIANT_int_iszero(
            running + sizeof(result->bitsnum) / sizeof(DWORD),
            (sizeof(running) - sizeof(result->bitsnum)) / sizeof(DWORD))) {
            
            remainder = VARIANT_int_divbychar(running, sizeof(running) / sizeof(DWORD), 10);
            if (remainder > 0) WARN("losing significant digits (remainder %u)...\n", remainder);
            result->scale--;
        }
        
        /* round up the result - native oleaut32 does this */
        if (remainder >= 5) {
            unsigned int i;
            for (remainder = 1, i = 0; i < sizeof(running)/sizeof(DWORD) && remainder; i++) {
                ULONGLONG digit = running[i] + 1;
                remainder = (digit > 0xFFFFFFFF) ? 1 : 0;
                running[i] = digit & 0xFFFFFFFF;
            }
        }

        /* Signal overflow if scale == 0 and 256-bit result still overflows,
           and copy result bits into result structure
        */
        r_overflow = !VARIANT_int_iszero(
            running + sizeof(result->bitsnum)/sizeof(DWORD), 
            (sizeof(running) - sizeof(result->bitsnum))/sizeof(DWORD));
        memcpy(result->bitsnum, running, sizeof(result->bitsnum));
    }
    return r_overflow;
}

/* cast DECIMAL into string. Any scale should be handled properly. en_US locale is
   hardcoded (period for decimal separator, dash as negative sign). Returns 0 for
   success, nonzero if insufficient space in output buffer.
 */
static int VARIANT_DI_tostringW(VARIANT_DI * a, WCHAR * s, unsigned int n)
{
    int overflow = 0;
    DWORD quotient[3];
    unsigned char remainder;
    unsigned int i;

    /* place negative sign */
    if (!VARIANT_int_iszero(a->bitsnum, sizeof(a->bitsnum) / sizeof(DWORD)) && a->sign) {
        if (n > 0) {
            *s++ = '-';
            n--;
        }
        else overflow = 1;
    }

    /* prepare initial 0 */
    if (!overflow) {
        if (n >= 2) {
            s[0] = '0';
            s[1] = '\0';
        } else overflow = 1;
    }

    i = 0;
    memcpy(quotient, a->bitsnum, sizeof(a->bitsnum));
    while (!overflow && !VARIANT_int_iszero(quotient, sizeof(quotient) / sizeof(DWORD))) {
        remainder = VARIANT_int_divbychar(quotient, sizeof(quotient) / sizeof(DWORD), 10);
        if (i + 2 > n) {
            overflow = 1;
        } else {
            s[i++] = '0' + remainder;
            s[i] = '\0';
        }
    }

    if (!overflow && !VARIANT_int_iszero(a->bitsnum, sizeof(a->bitsnum) / sizeof(DWORD))) {

        /* reverse order of digits */
        WCHAR * x = s; WCHAR * y = s + i - 1;
        while (x < y) {
            *x ^= *y;
            *y ^= *x;
            *x++ ^= *y--;
        }

        /* check for decimal point. "i" now has string length */
        if (i <= a->scale) {
            unsigned int numzeroes = a->scale + 1 - i;
            if (i + 1 + numzeroes >= n) {
                overflow = 1;
            } else {
                memmove(s + numzeroes, s, (i + 1) * sizeof(WCHAR));
                i += numzeroes;
                while (numzeroes > 0) {
                    s[--numzeroes] = '0';
                }
            }
        }

        /* place decimal point */
        if (a->scale > 0) {
            unsigned int periodpos = i - a->scale;
            if (i + 2 >= n) {
                overflow = 1;
            } else {
                memmove(s + periodpos + 1, s + periodpos, (i + 1 - periodpos) * sizeof(WCHAR));
                s[periodpos] = '.'; i++;
                
                /* remove extra zeros at the end, if any */
                while (s[i - 1] == '0') s[--i] = '\0';
                if (s[i - 1] == '.') s[--i] = '\0';
            }
        }
    }

    return overflow;
}

/* shift the bits of a DWORD array to the left. p[0] is assumed LSB */
static void VARIANT_int_shiftleft(DWORD * p, unsigned int n, unsigned int shift)
{
    DWORD shifted;
    unsigned int i;
    
    /* shift whole DWORDs to the left */
    while (shift >= 32)
    {
        memmove(p + 1, p, (n - 1) * sizeof(DWORD));
        *p = 0; shift -= 32;
    }
    
    /* shift remainder (1..31 bits) */
    shifted = 0;
    if (shift > 0) for (i = 0; i < n; i++)
    {
        DWORD b;
        b = p[i] >> (32 - shift);
        p[i] = (p[i] << shift) | shifted;
        shifted = b;
    }
}

/* add the (unsigned) numbers stored in two DWORD arrays with LSB at index 0.
   Value at v is incremented by the value at p. Any size is supported, provided
   that v is not shorter than p. Any unapplied carry is returned as a result.
 */
static unsigned char VARIANT_int_add(DWORD * v, unsigned int nv, DWORD * p, 
    unsigned int np)
{
    unsigned char carry = 0;

    if (nv >= np) {
        ULONGLONG sum;
        unsigned int i;

        for (i = 0; i < np; i++) {
            sum = (ULONGLONG)v[i]
                + (ULONGLONG)p[i]
                + (ULONGLONG)carry;
            v[i] = sum & 0xffffffff;
            carry = sum >> 32;
        }
        for (; i < nv && carry; i++) {
            sum = (ULONGLONG)v[i]
                + (ULONGLONG)carry;
            v[i] = sum & 0xffffffff;
            carry = sum >> 32;
        }
    }
    return carry;
}

/* perform integral division with operand p as dividend. Parameter n indicates 
   number of available DWORDs in divisor p, but available space in p must be 
   actually at least 2 * n DWORDs, because the remainder of the integral 
   division is built in the next n DWORDs past the start of the quotient. This 
   routine replaces the dividend in p with the quotient, and appends n 
   additional DWORDs for the remainder.

   Thanks to Lee & Mark Atkinson for their book _Using_C_ (my very first book on
   C/C++ :-) where the "longhand binary division" algorithm was exposed for the
   source code to the VLI (Very Large Integer) division operator. This algorithm
   was then heavily modified by me (Alex Villacis Lasso) in order to handle
   variably-scaled integers such as the MS DECIMAL representation.
 */
static void VARIANT_int_div(DWORD * p, unsigned int n, DWORD * divisor,
    unsigned int dn)
{
    unsigned int i;
    DWORD tempsub[8];
    DWORD * negdivisor = tempsub + n;

    /* build 2s-complement of divisor */
    for (i = 0; i < n; i++) negdivisor[i] = (i < dn) ? ~divisor[i] : 0xFFFFFFFF;
    p[n] = 1;
    VARIANT_int_add(negdivisor, n, p + n, 1);
    memset(p + n, 0, n * sizeof(DWORD));

    /* skip all leading zero DWORDs in quotient */
    for (i = 0; i < n && !p[n - 1]; i++) VARIANT_int_shiftleft(p, n, 32);
    /* i is now number of DWORDs left to process */
    for (i <<= 5; i < (n << 5); i++) {
        VARIANT_int_shiftleft(p, n << 1, 1);    /* shl quotient+remainder */

        /* trial subtraction */
        memcpy(tempsub, p + n, n * sizeof(DWORD));
        VARIANT_int_add(tempsub, n, negdivisor, n);

        /* check whether result of subtraction was negative */
        if ((tempsub[n - 1] & 0x80000000) == 0) {
            memcpy(p + n, tempsub, n * sizeof(DWORD));
            p[0] |= 1;
        }
    }
}

/* perform integral multiplication by a byte operand. Used for scaling by 10 */
static unsigned char VARIANT_int_mulbychar(DWORD * p, unsigned int n, unsigned char m)
{
    unsigned int i;
    ULONG iOverflowMul;
    
    for (iOverflowMul = 0, i = 0; i < n; i++)
        p[i] = VARIANT_Mul(p[i], m, &iOverflowMul);
    return (unsigned char)iOverflowMul;
}

/* increment value in A by the value indicated in B, with scale adjusting. 
   Modifies parameters by adjusting scales. Returns 0 if addition was 
   successful, nonzero if a parameter underflowed before it could be 
   successfully used in the addition.
 */
static int VARIANT_int_addlossy(
    DWORD * a, int * ascale, unsigned int an,
    DWORD * b, int * bscale, unsigned int bn)
{
    int underflow = 0;

    if (VARIANT_int_iszero(a, an)) {
        /* if A is zero, copy B into A, after removing digits */
        while (bn > an && !VARIANT_int_iszero(b + an, bn - an)) {
            VARIANT_int_divbychar(b, bn, 10);
            (*bscale)--;
        }
        memcpy(a, b, an * sizeof(DWORD));
        *ascale = *bscale;
    } else if (!VARIANT_int_iszero(b, bn)) {
        unsigned int tn = an + 1;
        DWORD t[5];

        if (bn + 1 > tn) tn = bn + 1;
        if (*ascale != *bscale) {
            /* first (optimistic) try - try to scale down the one with the bigger
               scale, while this number is divisible by 10 */
            DWORD * digitchosen;
            unsigned int nchosen;
            int * scalechosen;
            int targetscale;

            if (*ascale < *bscale) {
                targetscale = *ascale;
                scalechosen = bscale;
                digitchosen = b;
                nchosen = bn;
            } else {
                targetscale = *bscale;
                scalechosen = ascale;
                digitchosen = a;
                nchosen = an;
            }
            memset(t, 0, tn * sizeof(DWORD));
            memcpy(t, digitchosen, nchosen * sizeof(DWORD));

            /* divide by 10 until target scale is reached */
            while (*scalechosen > targetscale) {
                unsigned char remainder = VARIANT_int_divbychar(t, tn, 10);
                if (!remainder) {
                    (*scalechosen)--;
                    memcpy(digitchosen, t, nchosen * sizeof(DWORD));
                } else break;
            }
        }

        if (*ascale != *bscale) {
            DWORD * digitchosen;
            unsigned int nchosen;
            int * scalechosen;
            int targetscale;

            /* try to scale up the one with the smaller scale */
            if (*ascale > *bscale) {
                targetscale = *ascale;
                scalechosen = bscale;
                digitchosen = b;
                nchosen = bn;
            } else {
                targetscale = *bscale;
                scalechosen = ascale;
                digitchosen = a;
                nchosen = an;
            }
            memset(t, 0, tn * sizeof(DWORD));
            memcpy(t, digitchosen, nchosen * sizeof(DWORD));

            /* multiply by 10 until target scale is reached, or
               significant bytes overflow the number
             */
            while (*scalechosen < targetscale && t[nchosen] == 0) {
                VARIANT_int_mulbychar(t, tn, 10);
                if (t[nchosen] == 0) {
                    /* still does not overflow */
                    (*scalechosen)++;
                    memcpy(digitchosen, t, nchosen * sizeof(DWORD));
                }
            }
        }

        if (*ascale != *bscale) {
            /* still different? try to scale down the one with the bigger scale
               (this *will* lose significant digits) */
            DWORD * digitchosen;
            unsigned int nchosen;
            int * scalechosen;
            int targetscale;

            if (*ascale < *bscale) {
                targetscale = *ascale;
                scalechosen = bscale;
                digitchosen = b;
                nchosen = bn;
            } else {
                targetscale = *bscale;
                scalechosen = ascale;
                digitchosen = a;
                nchosen = an;
            }
            memset(t, 0, tn * sizeof(DWORD));
            memcpy(t, digitchosen, nchosen * sizeof(DWORD));

            /* divide by 10 until target scale is reached */
            while (*scalechosen > targetscale) {
                VARIANT_int_divbychar(t, tn, 10);
                (*scalechosen)--;
                memcpy(digitchosen, t, nchosen * sizeof(DWORD));
            }
        }

        /* check whether any of the operands still has significant digits
           (underflow case 1)
         */
        if (VARIANT_int_iszero(a, an) || VARIANT_int_iszero(b, bn)) {
            underflow = 1;
        } else {
            /* at this step, both numbers have the same scale and can be added
               as integers. However, the result might not fit in A, so further
               scaling down might be necessary.
             */
            while (!underflow) {
                memset(t, 0, tn * sizeof(DWORD));
                memcpy(t, a, an * sizeof(DWORD));

                VARIANT_int_add(t, tn, b, bn);
                if (VARIANT_int_iszero(t + an, tn - an)) {
                    /* addition was successful */
                    memcpy(a, t, an * sizeof(DWORD));
                    break;
                } else {
                    /* addition overflowed - remove significant digits
                       from both operands and try again */
                    VARIANT_int_divbychar(a, an, 10); (*ascale)--;
                    VARIANT_int_divbychar(b, bn, 10); (*bscale)--;
                    /* check whether any operand keeps significant digits after
                       scaledown (underflow case 2)
                     */
                    underflow = (VARIANT_int_iszero(a, an) || VARIANT_int_iszero(b, bn));
                }
            }
        }
    }
    return underflow;
}

/* perform complete DECIMAL division in the internal representation. Returns
   0 if the division was completed (even if quotient is set to 0), or nonzero
   in case of quotient overflow.
 */
static HRESULT VARIANT_DI_div(VARIANT_DI * dividend, VARIANT_DI * divisor, VARIANT_DI * quotient)
{
    HRESULT r_overflow = S_OK;

    if (VARIANT_int_iszero(divisor->bitsnum, sizeof(divisor->bitsnum)/sizeof(DWORD))) {
        /* division by 0 */
        r_overflow = DISP_E_DIVBYZERO;
    } else if (VARIANT_int_iszero(dividend->bitsnum, sizeof(dividend->bitsnum)/sizeof(DWORD))) {
        VARIANT_DI_clear(quotient);
    } else {
        int quotientscale, remainderscale, tempquotientscale;
        DWORD remainderplusquotient[8];
        int underflow;

        quotientscale = remainderscale = (int)dividend->scale - (int)divisor->scale;
        tempquotientscale = quotientscale;
        VARIANT_DI_clear(quotient);
        quotient->sign = (dividend->sign ^ divisor->sign) ? 1 : 0;

        /*  The following strategy is used for division
            1) if there was a nonzero remainder from previous iteration, use it as
               dividend for this iteration, else (for first iteration) use intended
               dividend
            2) perform integer division in temporary buffer, develop quotient in
               low-order part, remainder in high-order part
            3) add quotient from step 2 to final result, with possible loss of
               significant digits
            4) multiply integer part of remainder by 10, while incrementing the
               scale of the remainder. This operation preserves the intended value
               of the remainder.
            5) loop to step 1 until one of the following is true:
                a) remainder is zero (exact division achieved)
                b) addition in step 3 fails to modify bits in quotient (remainder underflow)
         */
        memset(remainderplusquotient, 0, sizeof(remainderplusquotient));
        memcpy(remainderplusquotient, dividend->bitsnum, sizeof(dividend->bitsnum));
        do {
            VARIANT_int_div(
                remainderplusquotient, 4,
                divisor->bitsnum, sizeof(divisor->bitsnum)/sizeof(DWORD));
            underflow = VARIANT_int_addlossy(
                quotient->bitsnum, &quotientscale, sizeof(quotient->bitsnum) / sizeof(DWORD),
                remainderplusquotient, &tempquotientscale, 4);
            VARIANT_int_mulbychar(remainderplusquotient + 4, 4, 10);
            memcpy(remainderplusquotient, remainderplusquotient + 4, 4 * sizeof(DWORD));
            tempquotientscale = ++remainderscale;
        } while (!underflow && !VARIANT_int_iszero(remainderplusquotient + 4, 4));

        /* quotient scale might now be negative (extremely big number). If, so, try
           to multiply quotient by 10 (without overflowing), while adjusting the scale,
           until scale is 0. If this cannot be done, it is a real overflow.
         */
        while (!r_overflow && quotientscale < 0) {
            memset(remainderplusquotient, 0, sizeof(remainderplusquotient));
            memcpy(remainderplusquotient, quotient->bitsnum, sizeof(quotient->bitsnum));
            VARIANT_int_mulbychar(remainderplusquotient, sizeof(remainderplusquotient)/sizeof(DWORD), 10);
            if (VARIANT_int_iszero(remainderplusquotient + sizeof(quotient->bitsnum)/sizeof(DWORD),
                (sizeof(remainderplusquotient) - sizeof(quotient->bitsnum))/sizeof(DWORD))) {
                quotientscale++;
                memcpy(quotient->bitsnum, remainderplusquotient, sizeof(quotient->bitsnum));
            } else r_overflow = DISP_E_OVERFLOW;
        }
        if (!r_overflow) {
            if (quotientscale <= 255) quotient->scale = quotientscale;
            else VARIANT_DI_clear(quotient);
        }
    }
    return r_overflow;
}

/************************************************************************
 * VarDecDiv (OLEAUT32.178)
 *
 * Divide one DECIMAL by another.
 *
 * PARAMS
 *  pDecLeft  [I] Source
 *  pDecRight [I] Value to divide by
 *  pDecOut   [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
 */
HRESULT WINAPI VarDecDiv(const DECIMAL* pDecLeft, const DECIMAL* pDecRight, DECIMAL* pDecOut)
{
  HRESULT hRet = S_OK;
  VARIANT_DI di_left, di_right, di_result;
  HRESULT divresult;

  if (!pDecLeft || !pDecRight || !pDecOut) return E_INVALIDARG;

  VARIANT_DIFromDec(pDecLeft, &di_left);
  VARIANT_DIFromDec(pDecRight, &di_right);
  divresult = VARIANT_DI_div(&di_left, &di_right, &di_result);
  if (divresult)
  {
      /* division actually overflowed */
      hRet = divresult;
  }
  else
  {
      hRet = S_OK;

      if (di_result.scale > DEC_MAX_SCALE)
      {
        unsigned char remainder = 0;
      
        /* division underflowed. In order to comply with the MSDN
           specifications for DECIMAL ranges, some significant digits
           must be removed
         */
        WARN("result scale is %u, scaling (with loss of significant digits)...\n",
            di_result.scale);
        while (di_result.scale > DEC_MAX_SCALE && 
               !VARIANT_int_iszero(di_result.bitsnum, sizeof(di_result.bitsnum) / sizeof(DWORD)))
        {
            remainder = VARIANT_int_divbychar(di_result.bitsnum, sizeof(di_result.bitsnum) / sizeof(DWORD), 10);
            di_result.scale--;
        }
        if (di_result.scale > DEC_MAX_SCALE)
        {
            WARN("result underflowed, setting to 0\n");
            di_result.scale = 0;
            di_result.sign = 0;
        }
        else if (remainder >= 5)    /* round up result - native oleaut32 does this */
        {
            unsigned int i;
            for (remainder = 1, i = 0; i < sizeof(di_result.bitsnum) / sizeof(DWORD) && remainder; i++) {
                ULONGLONG digit = di_result.bitsnum[i] + 1;
                remainder = (digit > 0xFFFFFFFF) ? 1 : 0;
                di_result.bitsnum[i] = digit & 0xFFFFFFFF;
            }
        }
      }
      VARIANT_DecFromDI(&di_result, pDecOut);
  }
  return hRet;
}

/************************************************************************
 * VarDecMul (OLEAUT32.179)
 *
 * Multiply one DECIMAL by another.
 *
 * PARAMS
 *  pDecLeft  [I] Source
 *  pDecRight [I] Value to multiply by
 *  pDecOut   [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
 */
HRESULT WINAPI VarDecMul(const DECIMAL* pDecLeft, const DECIMAL* pDecRight, DECIMAL* pDecOut)
{
  HRESULT hRet = S_OK;
  VARIANT_DI di_left, di_right, di_result;
  int mulresult;

  VARIANT_DIFromDec(pDecLeft, &di_left);
  VARIANT_DIFromDec(pDecRight, &di_right);
  mulresult = VARIANT_DI_mul(&di_left, &di_right, &di_result);
  if (mulresult)
  {
    /* multiplication actually overflowed */
    hRet = DISP_E_OVERFLOW;
  }
  else
  {
    if (di_result.scale > DEC_MAX_SCALE)
    {
      /* multiplication underflowed. In order to comply with the MSDN
         specifications for DECIMAL ranges, some significant digits
         must be removed
       */
      WARN("result scale is %u, scaling (with loss of significant digits)...\n",
          di_result.scale);
      while (di_result.scale > DEC_MAX_SCALE && 
            !VARIANT_int_iszero(di_result.bitsnum, sizeof(di_result.bitsnum)/sizeof(DWORD)))
      {
        VARIANT_int_divbychar(di_result.bitsnum, sizeof(di_result.bitsnum)/sizeof(DWORD), 10);
        di_result.scale--;
      }
      if (di_result.scale > DEC_MAX_SCALE)
      {
        WARN("result underflowed, setting to 0\n");
        di_result.scale = 0;
        di_result.sign = 0;
      }
    }
    VARIANT_DecFromDI(&di_result, pDecOut);
  }
  return hRet;
}

/************************************************************************
 * VarDecSub (OLEAUT32.181)
 *
 * Subtract one DECIMAL from another.
 *
 * PARAMS
 *  pDecLeft  [I] Source
 *  pDecRight [I] DECIMAL to subtract from pDecLeft
 *  pDecOut   [O] Destination
 *
 * RETURNS
 *  Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
 */
HRESULT WINAPI VarDecSub(const DECIMAL* pDecLeft, const DECIMAL* pDecRight, DECIMAL* pDecOut)
{
  DECIMAL decRight;

  /* Implement as addition of the negative */
  VarDecNeg(pDecRight, &decRight);
  return VarDecAdd(pDecLeft, &decRight, pDecOut);
}

/************************************************************************
 * VarDecAbs (OLEAUT32.182)
 *
 * Convert a DECIMAL into its absolute value.
 *
 * PARAMS
 *  pDecIn  [I] Source
 *  pDecOut [O] Destination
 *
 * RETURNS
 *  S_OK. This function does not fail.
 */
HRESULT WINAPI VarDecAbs(const DECIMAL* pDecIn, DECIMAL* pDecOut)
{
  *pDecOut = *pDecIn;
  DEC_SIGN(pDecOut) &= ~DECIMAL_NEG;
  return S_OK;
}

/************************************************************************
 * VarDecFix (OLEAUT32.187)
 *
 * Return the integer portion of a DECIMAL.
 *
 * PARAMS
 *  pDecIn  [I] Source
 *  pDecOut [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
 *
 * NOTES
 *  - The difference between this function and VarDecInt() is that VarDecInt() rounds
 *    negative numbers away from 0, while this function rounds them towards zero.
 */
HRESULT WINAPI VarDecFix(const DECIMAL* pDecIn, DECIMAL* pDecOut)
{
  if (DEC_SIGN(pDecIn) & ~DECIMAL_NEG)
    return E_INVALIDARG;

  if (!DEC_SCALE(pDecIn))
  {
    *pDecOut = *pDecIn; /* Already an integer */
    return S_OK;
  }

  FIXME("semi-stub!\n");
  return DISP_E_OVERFLOW;
}

/************************************************************************
 * VarDecInt (OLEAUT32.188)
 *
 * Return the integer portion of a DECIMAL.
 *
 * PARAMS
 *  pDecIn  [I] Source
 *  pDecOut [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
 *
 * NOTES
 *  - The difference between this function and VarDecFix() is that VarDecFix() rounds
 *    negative numbers towards 0, while this function rounds them away from zero.
 */
HRESULT WINAPI VarDecInt(const DECIMAL* pDecIn, DECIMAL* pDecOut)
{
  if (DEC_SIGN(pDecIn) & ~DECIMAL_NEG)
    return E_INVALIDARG;

  if (!(DEC_SIGN(pDecIn) & DECIMAL_NEG) || !DEC_SCALE(pDecIn))
    return VarDecFix(pDecIn, pDecOut); /* The same, if +ve or no fractionals */

  FIXME("semi-stub!\n");
  return DISP_E_OVERFLOW;
}

/************************************************************************
 * VarDecNeg (OLEAUT32.189)
 *
 * Change the sign of a DECIMAL.
 *
 * PARAMS
 *  pDecIn  [I] Source
 *  pDecOut [O] Destination
 *
 * RETURNS
 *  S_OK. This function does not fail.
 */
HRESULT WINAPI VarDecNeg(const DECIMAL* pDecIn, DECIMAL* pDecOut)
{
  *pDecOut = *pDecIn;
  DEC_SIGN(pDecOut) ^= DECIMAL_NEG;
  return S_OK;
}

/************************************************************************
 * VarDecRound (OLEAUT32.203)
 *
 * Change the precision of a DECIMAL.
 *
 * PARAMS
 *  pDecIn    [I] Source
 *  cDecimals [I] New number of decimals to keep
 *  pDecOut   [O] Destination
 *
 * RETURNS
 *  Success: S_OK. pDecOut contains the rounded value.
 *  Failure: E_INVALIDARG if any argument is invalid.
 */
HRESULT WINAPI VarDecRound(const DECIMAL* pDecIn, int cDecimals, DECIMAL* pDecOut)
{
  if (cDecimals < 0 || (DEC_SIGN(pDecIn) & ~DECIMAL_NEG) || DEC_SCALE(pDecIn) > DEC_MAX_SCALE)
    return E_INVALIDARG;

  if (cDecimals >= DEC_SCALE(pDecIn))
  {
    *pDecOut = *pDecIn; /* More precision than we have */
    return S_OK;
  }

  FIXME("semi-stub!\n");

  return DISP_E_OVERFLOW;
}

/************************************************************************
 * VarDecCmp (OLEAUT32.204)
 *
 * Compare two DECIMAL values.
 *
 * PARAMS
 *  pDecLeft  [I] Source
 *  pDecRight [I] Value to compare
 *
 * RETURNS
 *  Success: VARCMP_LT, VARCMP_EQ or VARCMP_GT indicating that pDecLeft
 *           is less than, equal to or greater than pDecRight respectively.
 *  Failure: DISP_E_OVERFLOW, if overflow occurs during the comparison
 */
HRESULT WINAPI VarDecCmp(const DECIMAL* pDecLeft, const DECIMAL* pDecRight)
{
  HRESULT hRet;
  DECIMAL result;

  /* Subtract right from left, and compare the result to 0 */
  hRet = VarDecSub(pDecLeft, pDecRight, &result);

  if (SUCCEEDED(hRet))
  {
    int non_zero = DEC_HI32(&result) | DEC_MID32(&result) | DEC_LO32(&result);

    if ((DEC_SIGN(&result) & DECIMAL_NEG) && non_zero)
      hRet = (HRESULT)VARCMP_LT;
    else if (non_zero)
      hRet = (HRESULT)VARCMP_GT;
    else
      hRet = (HRESULT)VARCMP_EQ;
  }
  return hRet;
}

/************************************************************************
 * VarDecCmpR8 (OLEAUT32.298)
 *
 * Compare a DECIMAL to a double
 *
 * PARAMS
 *  pDecLeft [I] DECIMAL Source
 *  dblRight [I] double to compare to pDecLeft
 *
 * RETURNS
 *  Success: VARCMP_LT, VARCMP_EQ or VARCMP_GT indicating that dblRight
 *           is less than, equal to or greater than pDecLeft respectively.
 *  Failure: DISP_E_OVERFLOW, if overflow occurs during the comparison
 */
HRESULT WINAPI VarDecCmpR8(const DECIMAL* pDecLeft, double dblRight)
{
  HRESULT hRet;
  DECIMAL decRight;

  hRet = VarDecFromR8(dblRight, &decRight);

  if (SUCCEEDED(hRet))
    hRet = VarDecCmp(pDecLeft, &decRight);

  return hRet;
}

/* BOOL
 */

/************************************************************************
 * VarBoolFromUI1 (OLEAUT32.118)
 *
 * Convert a VT_UI1 to a VT_BOOL.
 *
 * PARAMS
 *  bIn      [I] Source
 *  pBoolOut [O] Destination
 *
 * RETURNS
 *  S_OK.
 */
HRESULT WINAPI VarBoolFromUI1(BYTE bIn, VARIANT_BOOL *pBoolOut)
{
  *pBoolOut = bIn ? VARIANT_TRUE : VARIANT_FALSE;
  return S_OK;
}

/************************************************************************
 * VarBoolFromI2 (OLEAUT32.119)
 *
 * Convert a VT_I2 to a VT_BOOL.
 *
 * PARAMS
 *  sIn      [I] Source
 *  pBoolOut [O] Destination
 *
 * RETURNS
 *  S_OK.
 */
HRESULT WINAPI VarBoolFromI2(SHORT sIn, VARIANT_BOOL *pBoolOut)
{
  *pBoolOut = sIn ? VARIANT_TRUE : VARIANT_FALSE;
  return S_OK;
}

/************************************************************************
 * VarBoolFromI4 (OLEAUT32.120)
 *
 * Convert a VT_I4 to a VT_BOOL.
 *
 * PARAMS
 *  sIn      [I] Source
 *  pBoolOut [O] Destination
 *
 * RETURNS
 *  S_OK.
 */
HRESULT WINAPI VarBoolFromI4(LONG lIn, VARIANT_BOOL *pBoolOut)
{
  *pBoolOut = lIn ? VARIANT_TRUE : VARIANT_FALSE;
  return S_OK;
}

/************************************************************************
 * VarBoolFromR4 (OLEAUT32.121)
 *
 * Convert a VT_R4 to a VT_BOOL.
 *
 * PARAMS
 *  fltIn    [I] Source
 *  pBoolOut [O] Destination
 *
 * RETURNS
 *  S_OK.
 */
HRESULT WINAPI VarBoolFromR4(FLOAT fltIn, VARIANT_BOOL *pBoolOut)
{
  *pBoolOut = fltIn ? VARIANT_TRUE : VARIANT_FALSE;
  return S_OK;
}

/************************************************************************
 * VarBoolFromR8 (OLEAUT32.122)
 *
 * Convert a VT_R8 to a VT_BOOL.
 *
 * PARAMS
 *  dblIn    [I] Source
 *  pBoolOut [O] Destination
 *
 * RETURNS
 *  S_OK.
 */
HRESULT WINAPI VarBoolFromR8(double dblIn, VARIANT_BOOL *pBoolOut)
{
  *pBoolOut = dblIn ? VARIANT_TRUE : VARIANT_FALSE;
  return S_OK;
}

/************************************************************************
 * VarBoolFromDate (OLEAUT32.123)
 *
 * Convert a VT_DATE to a VT_BOOL.
 *
 * PARAMS
 *  dateIn   [I] Source
 *  pBoolOut [O] Destination
 *
 * RETURNS
 *  S_OK.
 */
HRESULT WINAPI VarBoolFromDate(DATE dateIn, VARIANT_BOOL *pBoolOut)
{
  *pBoolOut = dateIn ? VARIANT_TRUE : VARIANT_FALSE;
  return S_OK;
}

/************************************************************************
 * VarBoolFromCy (OLEAUT32.124)
 *
 * Convert a VT_CY to a VT_BOOL.
 *
 * PARAMS
 *  cyIn     [I] Source
 *  pBoolOut [O] Destination
 *
 * RETURNS
 *  S_OK.
 */
HRESULT WINAPI VarBoolFromCy(CY cyIn, VARIANT_BOOL *pBoolOut)
{
  *pBoolOut = cyIn.int64 ? VARIANT_TRUE : VARIANT_FALSE;
  return S_OK;
}

static BOOL VARIANT_GetLocalisedText(LANGID langId, DWORD dwId, WCHAR *lpszDest)
{
  HRSRC hrsrc;

  hrsrc = FindResourceExW( OLEAUT32_hModule, (LPWSTR)RT_STRING,
                           MAKEINTRESOURCEW((dwId >> 4) + 1), langId );
  if (hrsrc)
  {
    HGLOBAL hmem = LoadResource( OLEAUT32_hModule, hrsrc );

    if (hmem)
    {
      const WCHAR *p;
      unsigned int i;

      p = LockResource( hmem );
      for (i = 0; i < (dwId & 0x0f); i++) p += *p + 1;

      memcpy( lpszDest, p + 1, *p * sizeof(WCHAR) );
      lpszDest[*p] = '\0';
      TRACE("got %s for LANGID %08x\n", debugstr_w(lpszDest), langId);
      return TRUE;
    }
  }
  return FALSE;
}

/************************************************************************
 * VarBoolFromStr (OLEAUT32.125)
 *
 * Convert a VT_BSTR to a VT_BOOL.
 *
 * PARAMS
 *  strIn    [I] Source
 *  lcid     [I] LCID for the conversion
 *  dwFlags  [I] Flags controlling the conversion (VAR_ flags from "oleauto.h")
 *  pBoolOut [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if pBoolOut is invalid.
 *           DISP_E_TYPEMISMATCH, if the type cannot be converted
 *
 * NOTES
 *  - strIn will be recognised if it contains "#TRUE#" or "#FALSE#". Additionally,
 *  it may contain (in any case mapping) the text "true" or "false".
 *  - If dwFlags includes VAR_LOCALBOOL, then the text may also match the
 *  localised text of "True" or "False" in the language specified by lcid.
 *  - If none of these matches occur, the string is treated as a numeric string
 *  and the boolean pBoolOut will be set according to whether the number is zero
 *  or not. The dwFlags parameter is passed to VarR8FromStr() for this conversion.
 *  - If the text is not numeric and does not match any of the above, then
 *  DISP_E_TYPEMISMATCH is returned.
 */
HRESULT WINAPI VarBoolFromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, VARIANT_BOOL *pBoolOut)
{
  /* Any VB/VBA programmers out there should recognise these strings... */
  static const WCHAR szFalse[] = { '#','F','A','L','S','E','#','\0' };
  static const WCHAR szTrue[] = { '#','T','R','U','E','#','\0' };
  WCHAR szBuff[64];
  LANGID langId = MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT);
  HRESULT hRes = S_OK;

  if (!strIn || !pBoolOut)
    return DISP_E_TYPEMISMATCH;

  /* Check if we should be comparing against localised text */
  if (dwFlags & VAR_LOCALBOOL)
  {
    /* Convert our LCID into a usable value */
    lcid = ConvertDefaultLocale(lcid);

    langId = LANGIDFROMLCID(lcid);

    if (PRIMARYLANGID(langId) == LANG_NEUTRAL)
      langId = MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT);

    /* Note: Native oleaut32 always copies strIn and maps halfwidth characters.
     * I don't think this is needed unless any of the localised text strings
     * contain characters that can be so mapped. In the event that this is
     * true for a given language (possibly some Asian languages), then strIn
     * should be mapped here _only_ if langId is an Id for which this can occur.
     */
  }

  /* Note that if we are not comparing against localised strings, langId
   * will have its default value of LANG_ENGLISH. This allows us to mimic
   * the native behaviour of always checking against English strings even
   * after we've checked for localised ones.
   */
VarBoolFromStr_CheckLocalised:
  if (VARIANT_GetLocalisedText(langId, IDS_TRUE, szBuff))
  {
    /* Compare against localised strings, ignoring case */
    if (!strcmpiW(strIn, szBuff))
    {
      *pBoolOut = VARIANT_TRUE; /* Matched localised 'true' text */
      return hRes;
    }
    VARIANT_GetLocalisedText(langId, IDS_FALSE, szBuff);
    if (!strcmpiW(strIn, szBuff))
    {
      *pBoolOut = VARIANT_FALSE; /* Matched localised 'false' text */
      return hRes;
    }
  }

  if (langId != MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT))
  {
    /* We have checked the localised text, now check English */
    langId = MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT);
    goto VarBoolFromStr_CheckLocalised;
  }

  /* All checks against localised text have failed, try #TRUE#/#FALSE# */
  if (!strcmpW(strIn, szFalse))
    *pBoolOut = VARIANT_FALSE;
  else if (!strcmpW(strIn, szTrue))
    *pBoolOut = VARIANT_TRUE;
  else
  {
    double d;

    /* If this string is a number, convert it as one */
    hRes = VarR8FromStr(strIn, lcid, dwFlags, &d);
    if (SUCCEEDED(hRes)) *pBoolOut = d ? VARIANT_TRUE : VARIANT_FALSE;
  }
  return hRes;
}

/************************************************************************
 * VarBoolFromDisp (OLEAUT32.126)
 *
 * Convert a VT_DISPATCH to a VT_BOOL.
 *
 * PARAMS
 *  pdispIn   [I] Source
 *  lcid      [I] LCID for conversion
 *  pBoolOut  [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if the source value is invalid
 *           DISP_E_OVERFLOW, if the value will not fit in the destination
 *           DISP_E_TYPEMISMATCH, if the type cannot be converted
 */
HRESULT WINAPI VarBoolFromDisp(IDispatch* pdispIn, LCID lcid, VARIANT_BOOL *pBoolOut)
{
  return VARIANT_FromDisp(pdispIn, lcid, pBoolOut, VT_BOOL, 0);
}

/************************************************************************
 * VarBoolFromI1 (OLEAUT32.233)
 *
 * Convert a VT_I1 to a VT_BOOL.
 *
 * PARAMS
 *  cIn      [I] Source
 *  pBoolOut [O] Destination
 *
 * RETURNS
 *  S_OK.
 */
HRESULT WINAPI VarBoolFromI1(signed char cIn, VARIANT_BOOL *pBoolOut)
{
  *pBoolOut = cIn ? VARIANT_TRUE : VARIANT_FALSE;
  return S_OK;
}

/************************************************************************
 * VarBoolFromUI2 (OLEAUT32.234)
 *
 * Convert a VT_UI2 to a VT_BOOL.
 *
 * PARAMS
 *  usIn     [I] Source
 *  pBoolOut [O] Destination
 *
 * RETURNS
 *  S_OK.
 */
HRESULT WINAPI VarBoolFromUI2(USHORT usIn, VARIANT_BOOL *pBoolOut)
{
  *pBoolOut = usIn ? VARIANT_TRUE : VARIANT_FALSE;
  return S_OK;
}

/************************************************************************
 * VarBoolFromUI4 (OLEAUT32.235)
 *
 * Convert a VT_UI4 to a VT_BOOL.
 *
 * PARAMS
 *  ulIn     [I] Source
 *  pBoolOut [O] Destination
 *
 * RETURNS
 *  S_OK.
 */
HRESULT WINAPI VarBoolFromUI4(ULONG ulIn, VARIANT_BOOL *pBoolOut)
{
  *pBoolOut = ulIn ? VARIANT_TRUE : VARIANT_FALSE;
  return S_OK;
}

/************************************************************************
 * VarBoolFromDec (OLEAUT32.236)
 *
 * Convert a VT_DECIMAL to a VT_BOOL.
 *
 * PARAMS
 *  pDecIn   [I] Source
 *  pBoolOut [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if pDecIn is invalid.
 */
HRESULT WINAPI VarBoolFromDec(DECIMAL* pDecIn, VARIANT_BOOL *pBoolOut)
{
  if (DEC_SCALE(pDecIn) > DEC_MAX_SCALE || (DEC_SIGN(pDecIn) & ~DECIMAL_NEG))
    return E_INVALIDARG;

  if (DEC_HI32(pDecIn) || DEC_MID32(pDecIn) || DEC_LO32(pDecIn))
    *pBoolOut = VARIANT_TRUE;
  else
    *pBoolOut = VARIANT_FALSE;
  return S_OK;
}

/************************************************************************
 * VarBoolFromI8 (OLEAUT32.370)
 *
 * Convert a VT_I8 to a VT_BOOL.
 *
 * PARAMS
 *  ullIn    [I] Source
 *  pBoolOut [O] Destination
 *
 * RETURNS
 *  S_OK.
 */
HRESULT WINAPI VarBoolFromI8(LONG64 llIn, VARIANT_BOOL *pBoolOut)
{
  *pBoolOut = llIn ? VARIANT_TRUE : VARIANT_FALSE;
  return S_OK;
}

/************************************************************************
 * VarBoolFromUI8 (OLEAUT32.371)
 *
 * Convert a VT_UI8 to a VT_BOOL.
 *
 * PARAMS
 *  ullIn    [I] Source
 *  pBoolOut [O] Destination
 *
 * RETURNS
 *  S_OK.
 */
HRESULT WINAPI VarBoolFromUI8(ULONG64 ullIn, VARIANT_BOOL *pBoolOut)
{
  *pBoolOut = ullIn ? VARIANT_TRUE : VARIANT_FALSE;
  return S_OK;
}

/* BSTR
 */

/* Write a number from a UI8 and sign */
static WCHAR *VARIANT_WriteNumber(ULONG64 ulVal, WCHAR* szOut)
{
  do
  {
    WCHAR ulNextDigit = ulVal % 10;

    *szOut-- = '0' + ulNextDigit;
    ulVal = (ulVal - ulNextDigit) / 10;
  } while (ulVal);

  szOut++;
  return szOut;
}

/* Create a (possibly localised) BSTR from a UI8 and sign */
static BSTR VARIANT_MakeBstr(LCID lcid, DWORD dwFlags, WCHAR *szOut)
{
  WCHAR szConverted[256];

  if (dwFlags & VAR_NEGATIVE)
    *--szOut = '-';

  if (dwFlags & LOCALE_USE_NLS)
  {
    /* Format the number for the locale */
    szConverted[0] = '\0';
    GetNumberFormatW(lcid,
                     dwFlags & LOCALE_NOUSEROVERRIDE,
                     szOut, NULL, szConverted, sizeof(szConverted)/sizeof(WCHAR));
    szOut = szConverted;
  }
  return SysAllocStringByteLen((LPCSTR)szOut, strlenW(szOut) * sizeof(WCHAR));
}

/* Create a (possibly localised) BSTR from a UI8 and sign */
static HRESULT VARIANT_BstrFromUInt(ULONG64 ulVal, LCID lcid, DWORD dwFlags, BSTR *pbstrOut)
{
  WCHAR szBuff[64], *szOut = szBuff + sizeof(szBuff)/sizeof(WCHAR) - 1;

  if (!pbstrOut)
    return E_INVALIDARG;

  /* Create the basic number string */
  *szOut-- = '\0';
  szOut = VARIANT_WriteNumber(ulVal, szOut);

  *pbstrOut = VARIANT_MakeBstr(lcid, dwFlags, szOut);
  TRACE("returning %s\n", debugstr_w(*pbstrOut));
  return *pbstrOut ? S_OK : E_OUTOFMEMORY;
}

/******************************************************************************
 * VarBstrFromUI1 (OLEAUT32.108)
 *
 * Convert a VT_UI1 to a VT_BSTR.
 *
 * PARAMS
 *  bIn      [I] Source
 *  lcid     [I] LCID for the conversion
 *  dwFlags  [I] Flags controlling the conversion (VAR_ flags from "oleauto.h")
 *  pbstrOut [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if pbstrOut is invalid.
 *           E_OUTOFMEMORY, if memory allocation fails.
 */
HRESULT WINAPI VarBstrFromUI1(BYTE bIn, LCID lcid, ULONG dwFlags, BSTR* pbstrOut)
{
  return VARIANT_BstrFromUInt(bIn, lcid, dwFlags, pbstrOut);
}

/******************************************************************************
 * VarBstrFromI2 (OLEAUT32.109)
 *
 * Convert a VT_I2 to a VT_BSTR.
 *
 * PARAMS
 *  sIn      [I] Source
 *  lcid     [I] LCID for the conversion
 *  dwFlags  [I] Flags controlling the conversion (VAR_ flags from "oleauto.h")
 *  pbstrOut [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if pbstrOut is invalid.
 *           E_OUTOFMEMORY, if memory allocation fails.
 */
HRESULT WINAPI VarBstrFromI2(short sIn, LCID lcid, ULONG dwFlags, BSTR* pbstrOut)
{
  ULONG64 ul64 = sIn;

  if (sIn < 0)
  {
    ul64 = -sIn;
    dwFlags |= VAR_NEGATIVE;
  }
  return VARIANT_BstrFromUInt(ul64, lcid, dwFlags, pbstrOut);
}

/******************************************************************************
 * VarBstrFromI4 (OLEAUT32.110)
 *
 * Convert a VT_I4 to a VT_BSTR.
 *
 * PARAMS
 *  lIn      [I] Source
 *  lcid     [I] LCID for the conversion
 *  dwFlags  [I] Flags controlling the conversion (VAR_ flags from "oleauto.h")
 *  pbstrOut [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if pbstrOut is invalid.
 *           E_OUTOFMEMORY, if memory allocation fails.
 */
HRESULT WINAPI VarBstrFromI4(LONG lIn, LCID lcid, ULONG dwFlags, BSTR* pbstrOut)
{
  ULONG64 ul64 = lIn;

  if (lIn < 0)
  {
    ul64 = (ULONG)-lIn;
    dwFlags |= VAR_NEGATIVE;
  }
  return VARIANT_BstrFromUInt(ul64, lcid, dwFlags, pbstrOut);
}

static BSTR VARIANT_BstrReplaceDecimal(WCHAR * buff, LCID lcid, ULONG dwFlags)
{
  BSTR bstrOut;
  WCHAR lpDecimalSep[16];

  /* Native oleaut32 uses the locale-specific decimal separator even in the
     absence of the LOCALE_USE_NLS flag. For example, the Spanish/Latin 
     American locales will see "one thousand and one tenth" as "1000,1" 
     instead of "1000.1" (notice the comma). The following code checks for
     the need to replace the decimal separator, and if so, will prepare an
     appropriate NUMBERFMTW structure to do the job via GetNumberFormatW().
   */
  GetLocaleInfoW(lcid, LOCALE_SDECIMAL, lpDecimalSep, sizeof(lpDecimalSep) / sizeof(WCHAR));
  if (lpDecimalSep[0] == '.' && lpDecimalSep[1] == '\0')
  {
    /* locale is compatible with English - return original string */
    bstrOut = SysAllocString(buff);
  }
  else
  {
    WCHAR *p;
    WCHAR numbuff[256];
    WCHAR empty[1] = {'\0'};
    NUMBERFMTW minFormat;

    minFormat.NumDigits = 0;
    minFormat.LeadingZero = 0;
    minFormat.Grouping = 0;
    minFormat.lpDecimalSep = lpDecimalSep;
    minFormat.lpThousandSep = empty;
    minFormat.NegativeOrder = 1; /* NLS_NEG_LEFT */

    /* count number of decimal digits in string */
    p = strchrW( buff, '.' );
    if (p) minFormat.NumDigits = strlenW(p + 1);

    numbuff[0] = '\0';
    if (!GetNumberFormatW(lcid, dwFlags & LOCALE_NOUSEROVERRIDE,
                   buff, &minFormat, numbuff, sizeof(numbuff) / sizeof(WCHAR)))
    {
      WARN("GetNumberFormatW() failed, returning raw number string instead\n");
      bstrOut = SysAllocString(buff);
    }
    else
    {
      TRACE("created minimal NLS string %s\n", debugstr_w(numbuff));
      bstrOut = SysAllocString(numbuff);
    }
  }
  return bstrOut;
}

static HRESULT VARIANT_BstrFromReal(DOUBLE dblIn, LCID lcid, ULONG dwFlags,
                                    BSTR* pbstrOut, LPCWSTR lpszFormat)
{
  WCHAR buff[256];

  if (!pbstrOut)
    return E_INVALIDARG;

  sprintfW( buff, lpszFormat, dblIn );

  /* Negative zeroes are disallowed (some applications depend on this).
     If buff starts with a minus, and then nothing follows but zeroes
     and/or a period, it is a negative zero and is replaced with a
     canonical zero. This duplicates native oleaut32 behavior.
   */
  if (buff[0] == '-')
  {
    const WCHAR szAccept[] = {'0', '.', '\0'};
    if (strlenW(buff + 1) == strspnW(buff + 1, szAccept))
    { buff[0] = '0'; buff[1] = '\0'; }
  }

  TRACE("created string %s\n", debugstr_w(buff));
  if (dwFlags & LOCALE_USE_NLS)
  {
    WCHAR numbuff[256];

    /* Format the number for the locale */
    numbuff[0] = '\0';
    GetNumberFormatW(lcid, dwFlags & LOCALE_NOUSEROVERRIDE,
                     buff, NULL, numbuff, sizeof(numbuff) / sizeof(WCHAR));
    TRACE("created NLS string %s\n", debugstr_w(numbuff));
    *pbstrOut = SysAllocString(numbuff);
  }
  else
  {
    *pbstrOut = VARIANT_BstrReplaceDecimal(buff, lcid, dwFlags);
  }
  return *pbstrOut ? S_OK : E_OUTOFMEMORY;
}

/******************************************************************************
 * VarBstrFromR4 (OLEAUT32.111)
 *
 * Convert a VT_R4 to a VT_BSTR.
 *
 * PARAMS
 *  fltIn    [I] Source
 *  lcid     [I] LCID for the conversion
 *  dwFlags  [I] Flags controlling the conversion (VAR_ flags from "oleauto.h")
 *  pbstrOut [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if pbstrOut is invalid.
 *           E_OUTOFMEMORY, if memory allocation fails.
 */
HRESULT WINAPI VarBstrFromR4(FLOAT fltIn, LCID lcid, ULONG dwFlags, BSTR* pbstrOut)
{
  return VARIANT_BstrFromReal(fltIn, lcid, dwFlags, pbstrOut, szFloatFormatW);
}

/******************************************************************************
 * VarBstrFromR8 (OLEAUT32.112)
 *
 * Convert a VT_R8 to a VT_BSTR.
 *
 * PARAMS
 *  dblIn    [I] Source
 *  lcid     [I] LCID for the conversion
 *  dwFlags  [I] Flags controlling the conversion (VAR_ flags from "oleauto.h")
 *  pbstrOut [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if pbstrOut is invalid.
 *           E_OUTOFMEMORY, if memory allocation fails.
 */
HRESULT WINAPI VarBstrFromR8(double dblIn, LCID lcid, ULONG dwFlags, BSTR* pbstrOut)
{
  return VARIANT_BstrFromReal(dblIn, lcid, dwFlags, pbstrOut, szDoubleFormatW);
}

/******************************************************************************
 *    VarBstrFromCy   [OLEAUT32.113]
 *
 * Convert a VT_CY to a VT_BSTR.
 *
 * PARAMS
 *  cyIn     [I] Source
 *  lcid     [I] LCID for the conversion
 *  dwFlags  [I] Flags controlling the conversion (VAR_ flags from "oleauto.h")
 *  pbstrOut [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if pbstrOut is invalid.
 *           E_OUTOFMEMORY, if memory allocation fails.
 */
HRESULT WINAPI VarBstrFromCy(CY cyIn, LCID lcid, ULONG dwFlags, BSTR *pbstrOut)
{
  WCHAR buff[256];
  double dblVal;

  if (!pbstrOut)
    return E_INVALIDARG;

  VarR8FromCy(cyIn, &dblVal);
  sprintfW(buff, szDoubleFormatW, dblVal);

  if (dwFlags & LOCALE_USE_NLS)
  {
    WCHAR cybuff[256];

    /* Format the currency for the locale */
    cybuff[0] = '\0';
    GetCurrencyFormatW(lcid, dwFlags & LOCALE_NOUSEROVERRIDE,
                       buff, NULL, cybuff, sizeof(cybuff) / sizeof(WCHAR));
    *pbstrOut = SysAllocString(cybuff);
  }
  else
    *pbstrOut = SysAllocString(buff);

  return *pbstrOut ? S_OK : E_OUTOFMEMORY;
}

/******************************************************************************
 *    VarBstrFromDate    [OLEAUT32.114]
 *
 * Convert a VT_DATE to a VT_BSTR.
 *
 * PARAMS
 *  dateIn   [I] Source
 *  lcid     [I] LCID for the conversion
 *  dwFlags  [I] Flags controlling the conversion (VAR_ flags from "oleauto.h")
 *  pbstrOut [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if pbstrOut or dateIn is invalid.
 *           E_OUTOFMEMORY, if memory allocation fails.
 */
HRESULT WINAPI VarBstrFromDate(DATE dateIn, LCID lcid, ULONG dwFlags, BSTR* pbstrOut)
{
  SYSTEMTIME st;
  DWORD dwFormatFlags = dwFlags & LOCALE_NOUSEROVERRIDE;
  WCHAR date[128], *time;

  TRACE("(%g,0x%08lx,0x%08lx,%p)\n", dateIn, lcid, dwFlags, pbstrOut);

  if (!pbstrOut || !VariantTimeToSystemTime(dateIn, &st))
    return E_INVALIDARG;

  *pbstrOut = NULL;

  if (dwFlags & VAR_CALENDAR_THAI)
      st.wYear += 553; /* Use the Thai buddhist calendar year */
  else if (dwFlags & (VAR_CALENDAR_HIJRI|VAR_CALENDAR_GREGORIAN))
      FIXME("VAR_CALENDAR_HIJRI/VAR_CALENDAR_GREGORIAN not handled\n");

  if (dwFlags & LOCALE_USE_NLS)
    dwFlags &= ~(VAR_TIMEVALUEONLY|VAR_DATEVALUEONLY);
  else
  {
    double whole = dateIn < 0 ? ceil(dateIn) : floor(dateIn);
    double partial = dateIn - whole;

    if (whole == 0.0)
      dwFlags |= VAR_TIMEVALUEONLY;
    else if (partial < 1e-12)
      dwFlags |= VAR_DATEVALUEONLY;
  }

  if (dwFlags & VAR_TIMEVALUEONLY)
    date[0] = '\0';
  else
    if (!GetDateFormatW(lcid, dwFormatFlags|DATE_SHORTDATE, &st, NULL, date,
                        sizeof(date)/sizeof(WCHAR)))
      return E_INVALIDARG;

  if (!(dwFlags & VAR_DATEVALUEONLY))
  {
    time = date + strlenW(date);
    if (time != date)
      *time++ = ' ';
    if (!GetTimeFormatW(lcid, dwFormatFlags, &st, NULL, time,
                        sizeof(date)/sizeof(WCHAR)-(time-date)))
      return E_INVALIDARG;
  }

  *pbstrOut = SysAllocString(date);
  if (*pbstrOut)
    TRACE("returning %s\n", debugstr_w(*pbstrOut));
  return *pbstrOut ? S_OK : E_OUTOFMEMORY;
}

/******************************************************************************
 * VarBstrFromBool (OLEAUT32.116)
 *
 * Convert a VT_BOOL to a VT_BSTR.
 *
 * PARAMS
 *  boolIn   [I] Source
 *  lcid     [I] LCID for the conversion
 *  dwFlags  [I] Flags controlling the conversion (VAR_ flags from "oleauto.h")
 *  pbstrOut [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if pbstrOut is invalid.
 *           E_OUTOFMEMORY, if memory allocation fails.
 *
 * NOTES
 *  If dwFlags includes VARIANT_LOCALBOOL, this function converts to the
 *  localised text of "True" or "False". To convert a bool into a
 *  numeric string of "0" or "-1", use VariantChangeTypeTypeEx().
 */
HRESULT WINAPI VarBstrFromBool(VARIANT_BOOL boolIn, LCID lcid, ULONG dwFlags, BSTR* pbstrOut)
{
  WCHAR szBuff[64];
  DWORD dwResId = IDS_TRUE;
  LANGID langId;

  TRACE("%d,0x%08lx,0x%08lx,%p\n", boolIn, lcid, dwFlags, pbstrOut);

  if (!pbstrOut)
    return E_INVALIDARG;

  /* VAR_BOOLONOFF and VAR_BOOLYESNO are internal flags used
   * for variant formatting */
  switch (dwFlags & (VAR_LOCALBOOL|VAR_BOOLONOFF|VAR_BOOLYESNO))
  {
  case VAR_BOOLONOFF:
      dwResId = IDS_ON;
      break;
  case VAR_BOOLYESNO:
      dwResId = IDS_YES;
      break;
  case VAR_LOCALBOOL:
      break;
  default:
    lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT),SORT_DEFAULT);
  }

  lcid = ConvertDefaultLocale(lcid);
  langId = LANGIDFROMLCID(lcid);
  if (PRIMARYLANGID(langId) == LANG_NEUTRAL)
    langId = MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT);

  if (boolIn == VARIANT_FALSE)
    dwResId++; /* Use negative form */

VarBstrFromBool_GetLocalised:
  if (VARIANT_GetLocalisedText(langId, dwResId, szBuff))
  {
    *pbstrOut = SysAllocString(szBuff);
    return *pbstrOut ? S_OK : E_OUTOFMEMORY;
  }

  if (langId != MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT))
  {
    langId = MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT);
    goto VarBstrFromBool_GetLocalised;
  }

  /* Should never get here */
  WARN("Failed to load bool text!\n");
  return E_OUTOFMEMORY;
}

/******************************************************************************
 * VarBstrFromI1 (OLEAUT32.229)
 *
 * Convert a VT_I1 to a VT_BSTR.
 *
 * PARAMS
 *  cIn      [I] Source
 *  lcid     [I] LCID for the conversion
 *  dwFlags  [I] Flags controlling the conversion (VAR_ flags from "oleauto.h")
 *  pbstrOut [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if pbstrOut is invalid.
 *           E_OUTOFMEMORY, if memory allocation fails.
 */
HRESULT WINAPI VarBstrFromI1(signed char cIn, LCID lcid, ULONG dwFlags, BSTR* pbstrOut)
{
  ULONG64 ul64 = cIn;

  if (cIn < 0)
  {
    ul64 = -cIn;
    dwFlags |= VAR_NEGATIVE;
  }
  return VARIANT_BstrFromUInt(ul64, lcid, dwFlags, pbstrOut);
}

/******************************************************************************
 * VarBstrFromUI2 (OLEAUT32.230)
 *
 * Convert a VT_UI2 to a VT_BSTR.
 *
 * PARAMS
 *  usIn     [I] Source
 *  lcid     [I] LCID for the conversion
 *  dwFlags  [I] Flags controlling the conversion (VAR_ flags from "oleauto.h")
 *  pbstrOut [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if pbstrOut is invalid.
 *           E_OUTOFMEMORY, if memory allocation fails.
 */
HRESULT WINAPI VarBstrFromUI2(USHORT usIn, LCID lcid, ULONG dwFlags, BSTR* pbstrOut)
{
  return VARIANT_BstrFromUInt(usIn, lcid, dwFlags, pbstrOut);
}

/******************************************************************************
 * VarBstrFromUI4 (OLEAUT32.231)
 *
 * Convert a VT_UI4 to a VT_BSTR.
 *
 * PARAMS
 *  ulIn     [I] Source
 *  lcid     [I] LCID for the conversion
 *  dwFlags  [I] Flags controlling the conversion (VAR_ flags from "oleauto.h")
 *  pbstrOut [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if pbstrOut is invalid.
 *           E_OUTOFMEMORY, if memory allocation fails.
 */
HRESULT WINAPI VarBstrFromUI4(ULONG ulIn, LCID lcid, ULONG dwFlags, BSTR* pbstrOut)
{
  return VARIANT_BstrFromUInt(ulIn, lcid, dwFlags, pbstrOut);
}

/******************************************************************************
 * VarBstrFromDec (OLEAUT32.232)
 *
 * Convert a VT_DECIMAL to a VT_BSTR.
 *
 * PARAMS
 *  pDecIn   [I] Source
 *  lcid     [I] LCID for the conversion
 *  dwFlags  [I] Flags controlling the conversion (VAR_ flags from "oleauto.h")
 *  pbstrOut [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if pbstrOut is invalid.
 *           E_OUTOFMEMORY, if memory allocation fails.
 */
HRESULT WINAPI VarBstrFromDec(DECIMAL* pDecIn, LCID lcid, ULONG dwFlags, BSTR* pbstrOut)
{
  WCHAR buff[256];
  VARIANT_DI temp;

  if (!pbstrOut)
    return E_INVALIDARG;

  VARIANT_DIFromDec(pDecIn, &temp);
  VARIANT_DI_tostringW(&temp, buff, 256);

  if (dwFlags & LOCALE_USE_NLS)
  {
    WCHAR numbuff[256];

    /* Format the number for the locale */
    numbuff[0] = '\0';
    GetNumberFormatW(lcid, dwFlags & LOCALE_NOUSEROVERRIDE,
                     buff, NULL, numbuff, sizeof(numbuff) / sizeof(WCHAR));
    TRACE("created NLS string %s\n", debugstr_w(numbuff));
    *pbstrOut = SysAllocString(numbuff);
  }
  else
  {
    *pbstrOut = VARIANT_BstrReplaceDecimal(buff, lcid, dwFlags);
  }
  
  TRACE("returning %s\n", debugstr_w(*pbstrOut));
  return *pbstrOut ? S_OK : E_OUTOFMEMORY;
}

/************************************************************************
 * VarBstrFromI8 (OLEAUT32.370)
 *
 * Convert a VT_I8 to a VT_BSTR.
 *
 * PARAMS
 *  llIn     [I] Source
 *  lcid     [I] LCID for the conversion
 *  dwFlags  [I] Flags controlling the conversion (VAR_ flags from "oleauto.h")
 *  pbstrOut [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if pbstrOut is invalid.
 *           E_OUTOFMEMORY, if memory allocation fails.
 */
HRESULT WINAPI VarBstrFromI8(LONG64 llIn, LCID lcid, ULONG dwFlags, BSTR* pbstrOut)
{
  ULONG64 ul64 = llIn;

  if (llIn < 0)
  {
    ul64 = -llIn;
    dwFlags |= VAR_NEGATIVE;
  }
  return VARIANT_BstrFromUInt(ul64, lcid, dwFlags, pbstrOut);
}

/************************************************************************
 * VarBstrFromUI8 (OLEAUT32.371)
 *
 * Convert a VT_UI8 to a VT_BSTR.
 *
 * PARAMS
 *  ullIn    [I] Source
 *  lcid     [I] LCID for the conversion
 *  dwFlags  [I] Flags controlling the conversion (VAR_ flags from "oleauto.h")
 *  pbstrOut [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if pbstrOut is invalid.
 *           E_OUTOFMEMORY, if memory allocation fails.
 */
HRESULT WINAPI VarBstrFromUI8(ULONG64 ullIn, LCID lcid, ULONG dwFlags, BSTR* pbstrOut)
{
  return VARIANT_BstrFromUInt(ullIn, lcid, dwFlags, pbstrOut);
}

/************************************************************************
 * VarBstrFromDisp (OLEAUT32.115)
 *
 * Convert a VT_DISPATCH to a BSTR.
 *
 * PARAMS
 *  pdispIn [I] Source
 *  lcid    [I] LCID for conversion
 *  dwFlags [I] Flags controlling the conversion (VAR_ flags from "oleauto.h")
 *  pbstrOut  [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if the source value is invalid
 *           DISP_E_TYPEMISMATCH, if the type cannot be converted
 */
HRESULT WINAPI VarBstrFromDisp(IDispatch* pdispIn, LCID lcid, ULONG dwFlags, BSTR* pbstrOut)
{
  return VARIANT_FromDisp(pdispIn, lcid, pbstrOut, VT_BSTR, dwFlags);
}

/**********************************************************************
 * VarBstrCat (OLEAUT32.313)
 *
 * Concatenate two BSTR values.
 *
 * PARAMS
 *  pbstrLeft  [I] Source
 *  pbstrRight [I] Value to concatenate
 *  pbstrOut   [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if pbstrOut is invalid.
 *           E_OUTOFMEMORY, if memory allocation fails.
 */
HRESULT WINAPI VarBstrCat(BSTR pbstrLeft, BSTR pbstrRight, BSTR *pbstrOut)
{
  unsigned int len;

  if (!pbstrOut)
    return E_INVALIDARG;

  len = pbstrLeft ? strlenW(pbstrLeft) : 0;
  if (pbstrRight)
    len += strlenW(pbstrRight);

  *pbstrOut = SysAllocStringLen(NULL, len);
  if (!*pbstrOut)
    return E_OUTOFMEMORY;

  (*pbstrOut)[0] = '\0';

  if (pbstrLeft)
    strcpyW(*pbstrOut, pbstrLeft);

  if (pbstrRight)
    strcatW(*pbstrOut, pbstrRight);

  return S_OK;
}

/**********************************************************************
 * VarBstrCmp (OLEAUT32.314)
 *
 * Compare two BSTR values.
 *
 * PARAMS
 *  pbstrLeft  [I] Source
 *  pbstrRight [I] Value to compare
 *  lcid       [I] LCID for the comparison
 *  dwFlags    [I] Flags to pass directly to CompareStringW().
 *
 * RETURNS
 *  VARCMP_LT, VARCMP_EQ or VARCMP_GT indicating that pbstrLeft is less
 *  than, equal to or greater than pbstrRight respectively.
 *
 * NOTES
 *  VARCMP_NULL is NOT returned if either string is NULL unlike MSDN
 *  states. A NULL BSTR pointer is equivalent to an empty string.
 */
HRESULT WINAPI VarBstrCmp(BSTR pbstrLeft, BSTR pbstrRight, LCID lcid, DWORD dwFlags)
{
    if (!pbstrLeft || !*pbstrLeft)
    {
      if (!pbstrRight || !*pbstrRight)
        return VARCMP_EQ;
      return VARCMP_LT;
    }
    else if (!pbstrRight || !*pbstrRight)
        return VARCMP_GT;

    return CompareStringW(lcid, dwFlags, pbstrLeft, -1, pbstrRight, -1) - 1;
}

/*
 * DATE
 */

/******************************************************************************
 * VarDateFromUI1 (OLEAUT32.88)
 *
 * Convert a VT_UI1 to a VT_DATE.
 *
 * PARAMS
 *  bIn      [I] Source
 *  pdateOut [O] Destination
 *
 * RETURNS
 *  S_OK.
 */
HRESULT WINAPI VarDateFromUI1(BYTE bIn, DATE* pdateOut)
{
  return VarR8FromUI1(bIn, pdateOut);
}

/******************************************************************************
 * VarDateFromI2 (OLEAUT32.89)
 *
 * Convert a VT_I2 to a VT_DATE.
 *
 * PARAMS
 *  sIn      [I] Source
 *  pdateOut [O] Destination
 *
 * RETURNS
 *  S_OK.
 */
HRESULT WINAPI VarDateFromI2(short sIn, DATE* pdateOut)
{
  return VarR8FromI2(sIn, pdateOut);
}

/******************************************************************************
 * VarDateFromI4 (OLEAUT32.90)
 *
 * Convert a VT_I4 to a VT_DATE.
 *
 * PARAMS
 *  lIn      [I] Source
 *  pdateOut [O] Destination
 *
 * RETURNS
 *  S_OK.
 */
HRESULT WINAPI VarDateFromI4(LONG lIn, DATE* pdateOut)
{
  return VarDateFromR8(lIn, pdateOut);
}

/******************************************************************************
 * VarDateFromR4 (OLEAUT32.91)
 *
 * Convert a VT_R4 to a VT_DATE.
 *
 * PARAMS
 *  fltIn    [I] Source
 *  pdateOut [O] Destination
 *
 * RETURNS
 *  S_OK.
 */
HRESULT WINAPI VarDateFromR4(FLOAT fltIn, DATE* pdateOut)
{
  return VarR8FromR4(fltIn, pdateOut);
}

/******************************************************************************
 * VarDateFromR8 (OLEAUT32.92)
 *
 * Convert a VT_R8 to a VT_DATE.
 *
 * PARAMS
 *  dblIn    [I] Source
 *  pdateOut [O] Destination
 *
 * RETURNS
 *  S_OK.
 */
HRESULT WINAPI VarDateFromR8(double dblIn, DATE* pdateOut)
{
  if (dblIn <= (DATE_MIN - 1.0) || dblIn >= (DATE_MAX + 1.0)) return DISP_E_OVERFLOW;
  *pdateOut = (DATE)dblIn;
  return S_OK;
}

/**********************************************************************
 * VarDateFromDisp (OLEAUT32.95)
 *
 * Convert a VT_DISPATCH to a VT_DATE.
 *
 * PARAMS
 *  pdispIn  [I] Source
 *  lcid     [I] LCID for conversion
 *  pdateOut [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: E_INVALIDARG, if the source value is invalid
 *           DISP_E_OVERFLOW, if the value will not fit in the destination
 *           DISP_E_TYPEMISMATCH, if the type cannot be converted
 */
HRESULT WINAPI VarDateFromDisp(IDispatch* pdispIn, LCID lcid, DATE* pdateOut)
{
  return VARIANT_FromDisp(pdispIn, lcid, pdateOut, VT_DATE, 0);
}

/******************************************************************************
 * VarDateFromBool (OLEAUT32.96)
 *
 * Convert a VT_BOOL to a VT_DATE.
 *
 * PARAMS
 *  boolIn   [I] Source
 *  pdateOut [O] Destination
 *
 * RETURNS
 *  S_OK.
 */
HRESULT WINAPI VarDateFromBool(VARIANT_BOOL boolIn, DATE* pdateOut)
{
  return VarR8FromBool(boolIn, pdateOut);
}

/**********************************************************************
 * VarDateFromCy (OLEAUT32.93)
 *
 * Convert a VT_CY to a VT_DATE.
 *
 * PARAMS
 *  lIn      [I] Source
 *  pdateOut [O] Destination
 *
 * RETURNS
 *  S_OK.
 */
HRESULT WINAPI VarDateFromCy(CY cyIn, DATE* pdateOut)
{
  return VarR8FromCy(cyIn, pdateOut);
}

/* Date string parsing */
#define DP_TIMESEP 0x01 /* Time separator ( _must_ remain 0x1, used as a bitmask) */
#define DP_DATESEP 0x02 /* Date separator */
#define DP_MONTH   0x04 /* Month name */
#define DP_AM      0x08 /* AM */
#define DP_PM      0x10 /* PM */

typedef struct tagDATEPARSE
{
    DWORD dwCount;      /* Number of fields found so far (maximum 6) */
    DWORD dwParseFlags; /* Global parse flags (DP_ Flags above) */
    DWORD dwFlags[6];   /* Flags for each field */
    DWORD dwValues[6];  /* Value of each field */
} DATEPARSE;

#define TIMEFLAG(i) ((dp.dwFlags[i] & DP_TIMESEP) << i)

#define IsLeapYear(y) (((y % 4) == 0) && (((y % 100) != 0) || ((y % 400) == 0)))

/* Determine if a day is valid in a given month of a given year */
static BOOL VARIANT_IsValidMonthDay(DWORD day, DWORD month, DWORD year)
{
  static const BYTE days[] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

  if (day && month && month < 13)
  {
    if (day <= days[month] || (month == 2 && day == 29 && IsLeapYear(year)))
      return TRUE;
  }
  return FALSE;
}

/* Possible orders for 3 numbers making up a date */
#define ORDER_MDY 0x01
#define ORDER_YMD 0x02
#define ORDER_YDM 0x04
#define ORDER_DMY 0x08
#define ORDER_MYD 0x10 /* Synthetic order, used only for funky 2 digit dates */

/* Determine a date for a particular locale, from 3 numbers */
static inline HRESULT VARIANT_MakeDate(DATEPARSE *dp, DWORD iDate,
                                       DWORD offset, SYSTEMTIME *st)
{
  DWORD dwAllOrders, dwTry, dwCount = 0, v1, v2, v3;

  if (!dp->dwCount)
  {
    v1 = 30; /* Default to (Variant) 0 date part */
    v2 = 12;
    v3 = 1899;
    goto VARIANT_MakeDate_OK;
  }

  v1 = dp->dwValues[offset + 0];
  v2 = dp->dwValues[offset + 1];
  if (dp->dwCount == 2)
  {
    SYSTEMTIME current;
    GetSystemTime(&current);
    v3 = current.wYear;
  }
  else
    v3 = dp->dwValues[offset + 2];

  TRACE("(%ld,%ld,%ld,%ld,%ld)\n", v1, v2, v3, iDate, offset);

  /* If one number must be a month (Because a month name was given), then only
   * consider orders with the month in that position.
   * If we took the current year as 'v3', then only allow a year in that position.
   */
  if (dp->dwFlags[offset + 0] & DP_MONTH)
  {
    dwAllOrders = ORDER_MDY;
  }
  else if (dp->dwFlags[offset + 1] & DP_MONTH)
  {
    dwAllOrders = ORDER_DMY;
    if (dp->dwCount > 2)
      dwAllOrders |= ORDER_YMD;
  }
  else if (dp->dwCount > 2 && dp->dwFlags[offset + 2] & DP_MONTH)
  {
    dwAllOrders = ORDER_YDM;
  }
  else
  {
    dwAllOrders = ORDER_MDY|ORDER_DMY;
    if (dp->dwCount > 2)
      dwAllOrders |= (ORDER_YMD|ORDER_YDM);
  }

VARIANT_MakeDate_Start:
  TRACE("dwAllOrders is 0x%08lx\n", dwAllOrders);

  while (dwAllOrders)
  {
    DWORD dwTemp;

    if (dwCount == 0)
    {
      /* First: Try the order given by iDate */
      switch (iDate)
      {
      case 0:  dwTry = dwAllOrders & ORDER_MDY; break;
      case 1:  dwTry = dwAllOrders & ORDER_DMY; break;
      default: dwTry = dwAllOrders & ORDER_YMD; break;
      }
    }
    else if (dwCount == 1)
    {
      /* Second: Try all the orders compatible with iDate */
      switch (iDate)
      {
      case 0:  dwTry = dwAllOrders & ~(ORDER_DMY|ORDER_YDM); break;
      case 1:  dwTry = dwAllOrders & ~(ORDER_MDY|ORDER_YMD|ORDER_MYD); break;
      default: dwTry = dwAllOrders & ~(ORDER_DMY|ORDER_YDM); break;
      }
    }
    else
    {
      /* Finally: Try any remaining orders */
      dwTry = dwAllOrders;
    }

    TRACE("Attempt %ld, dwTry is 0x%08lx\n", dwCount, dwTry);

    dwCount++;
    if (!dwTry)
      continue;

#define DATE_SWAP(x,y) do { dwTemp = x; x = y; y = dwTemp; } while (0)

    if (dwTry & ORDER_MDY)
    {
      if (VARIANT_IsValidMonthDay(v2,v1,v3))
      {
        DATE_SWAP(v1,v2);
        goto VARIANT_MakeDate_OK;
      }
      dwAllOrders &= ~ORDER_MDY;
    }
    if (dwTry & ORDER_YMD)
    {
      if (VARIANT_IsValidMonthDay(v3,v2,v1))
      {
        DATE_SWAP(v1,v3);
        goto VARIANT_MakeDate_OK;
      }
      dwAllOrders &= ~ORDER_YMD;
    }
    if (dwTry & ORDER_YDM)
    {
      if (VARIANT_IsValidMonthDay(v2,v3,v1))
      {
        DATE_SWAP(v1,v2);
        DATE_SWAP(v2,v3);
        goto VARIANT_MakeDate_OK;
      }
      dwAllOrders &= ~ORDER_YDM;
    }
    if (dwTry & ORDER_DMY)
    {
      if (VARIANT_IsValidMonthDay(v1,v2,v3))
        goto VARIANT_MakeDate_OK;
      dwAllOrders &= ~ORDER_DMY;
    }
    if (dwTry & ORDER_MYD)
    {
      /* Only occurs if we are trying a 2 year date as M/Y not D/M */
      if (VARIANT_IsValidMonthDay(v3,v1,v2))
      {
        DATE_SWAP(v1,v3);
        DATE_SWAP(v2,v3);
        goto VARIANT_MakeDate_OK;
      }
      dwAllOrders &= ~ORDER_MYD;
    }
  }

  if (dp->dwCount == 2)
  {
    /* We couldn't make a date as D/M or M/D, so try M/Y or Y/M */
    v3 = 1; /* 1st of the month */
    dwAllOrders = ORDER_YMD|ORDER_MYD;
    dp->dwCount = 0; /* Don't return to this code path again */
    dwCount = 0;
    goto VARIANT_MakeDate_Start;
  }

  /* No valid dates were able to be constructed */
  return DISP_E_TYPEMISMATCH;

VARIANT_MakeDate_OK:

  /* Check that the time part is ok */
  if (st->wHour > 23 || st->wMinute > 59 || st->wSecond > 59)
    return DISP_E_TYPEMISMATCH;

  TRACE("Time %d %d %d\n", st->wHour, st->wMinute, st->wSecond);
  if (st->wHour < 12 && (dp->dwParseFlags & DP_PM))
    st->wHour += 12;
  else if (st->wHour == 12 && (dp->dwParseFlags & DP_AM))
    st->wHour = 0;
  TRACE("Time %d %d %d\n", st->wHour, st->wMinute, st->wSecond);

  st->wDay = v1;
  st->wMonth = v2;
  /* FIXME: For 2 digit dates, I'm not sure if 30 is hard coded or not. It may
   * be retrieved from:
   * HKCU\Control Panel\International\Calendars\TwoDigitYearMax
   * But Wine doesn't have/use that key as at the time of writing.
   */
  st->wYear = v3 < 30 ? 2000 + v3 : v3 < 100 ? 1900 + v3 : v3;
  TRACE("Returning date %ld/%ld/%d\n", v1, v2, st->wYear);
  return S_OK;
}

/******************************************************************************
 * VarDateFromStr [OLEAUT32.94]
 *
 * Convert a VT_BSTR to at VT_DATE.
 *
 * PARAMS
 *  strIn    [I] String to convert
 *  lcid     [I] Locale identifier for the conversion
 *  dwFlags  [I] Flags affecting the conversion (VAR_ flags from "oleauto.h")
 *  pdateOut [O] Destination for the converted value
 *
 * RETURNS
 *  Success: S_OK. pdateOut contains the converted value.
 *  FAILURE: An HRESULT error code indicating the prolem.
 *
 * NOTES
 *  Any date format that can be created using the date formats from lcid
 *  (Either from kernel Nls functions, variant conversion or formatting) is a
 *  valid input to this function. In addition, a few more esoteric formats are
 *  also supported for compatibility with the native version. The date is
 *  interpreted according to the date settings in the control panel, unless
 *  the date is invalid in that format, in which the most compatible format
 *  that produces a valid date will be used.
 */
HRESULT WINAPI VarDateFromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, DATE* pdateOut)
{
  static const USHORT ParseDateTokens[] =
  {
    LOCALE_SMONTHNAME1, LOCALE_SMONTHNAME2, LOCALE_SMONTHNAME3, LOCALE_SMONTHNAME4,
    LOCALE_SMONTHNAME5, LOCALE_SMONTHNAME6, LOCALE_SMONTHNAME7, LOCALE_SMONTHNAME8,
    LOCALE_SMONTHNAME9, LOCALE_SMONTHNAME10, LOCALE_SMONTHNAME11, LOCALE_SMONTHNAME12,
    LOCALE_SMONTHNAME13,
    LOCALE_SABBREVMONTHNAME1, LOCALE_SABBREVMONTHNAME2, LOCALE_SABBREVMONTHNAME3,
    LOCALE_SABBREVMONTHNAME4, LOCALE_SABBREVMONTHNAME5, LOCALE_SABBREVMONTHNAME6,
    LOCALE_SABBREVMONTHNAME7, LOCALE_SABBREVMONTHNAME8, LOCALE_SABBREVMONTHNAME9,
    LOCALE_SABBREVMONTHNAME10, LOCALE_SABBREVMONTHNAME11, LOCALE_SABBREVMONTHNAME12,
    LOCALE_SABBREVMONTHNAME13,
    LOCALE_SDAYNAME1, LOCALE_SDAYNAME2, LOCALE_SDAYNAME3, LOCALE_SDAYNAME4,
    LOCALE_SDAYNAME5, LOCALE_SDAYNAME6, LOCALE_SDAYNAME7,
    LOCALE_SABBREVDAYNAME1, LOCALE_SABBREVDAYNAME2, LOCALE_SABBREVDAYNAME3,
    LOCALE_SABBREVDAYNAME4, LOCALE_SABBREVDAYNAME5, LOCALE_SABBREVDAYNAME6,
    LOCALE_SABBREVDAYNAME7,
    LOCALE_S1159, LOCALE_S2359
  };
  static const BYTE ParseDateMonths[] =
  {
    1,2,3,4,5,6,7,8,9,10,11,12,13,
    1,2,3,4,5,6,7,8,9,10,11,12,13
  };
  size_t i;
  BSTR tokens[sizeof(ParseDateTokens)/sizeof(ParseDateTokens[0])];
  DATEPARSE dp;
  DWORD dwDateSeps = 0, iDate = 0;
  HRESULT hRet = S_OK;

  if ((dwFlags & (VAR_TIMEVALUEONLY|VAR_DATEVALUEONLY)) ==
      (VAR_TIMEVALUEONLY|VAR_DATEVALUEONLY))
    return E_INVALIDARG;

  if (!strIn)
    return DISP_E_TYPEMISMATCH;

  *pdateOut = 0.0;

  TRACE("(%s,0x%08lx,0x%08lx,%p)\n", debugstr_w(strIn), lcid, dwFlags, pdateOut);

  memset(&dp, 0, sizeof(dp));

  GetLocaleInfoW(lcid, LOCALE_IDATE|LOCALE_RETURN_NUMBER|(dwFlags & LOCALE_NOUSEROVERRIDE),
                 (LPWSTR)&iDate, sizeof(iDate)/sizeof(WCHAR));
  TRACE("iDate is %ld\n", iDate);

  /* Get the month/day/am/pm tokens for this locale */
  for (i = 0; i < sizeof(tokens)/sizeof(tokens[0]); i++)
  {
    WCHAR buff[128];
    LCTYPE lctype =  ParseDateTokens[i] | (dwFlags & LOCALE_NOUSEROVERRIDE);

    /* FIXME: Alternate calendars - should use GetCalendarInfo() and/or
     *        GetAltMonthNames(). We should really cache these strings too.
     */
    buff[0] = '\0';
    GetLocaleInfoW(lcid, lctype, buff, sizeof(buff)/sizeof(WCHAR));
    tokens[i] = SysAllocString(buff);
    TRACE("token %d is %s\n", i, debugstr_w(tokens[i]));
  }

  /* Parse the string into our structure */
  while (*strIn)
  {
    if (dp.dwCount > 6)
      break;

    if (isdigitW(*strIn))
    {
      dp.dwValues[dp.dwCount] = strtoulW(strIn, &strIn, 10);
      dp.dwCount++;
      strIn--;
    }
    else if (isalpha(*strIn))
    {
      BOOL bFound = FALSE;

      for (i = 0; i < sizeof(tokens)/sizeof(tokens[0]); i++)
      {
        DWORD dwLen = strlenW(tokens[i]);
        if (dwLen && !strncmpiW(strIn, tokens[i], dwLen))
        {
          if (i <= 25)
          {
            dp.dwValues[dp.dwCount] = ParseDateMonths[i];
            dp.dwFlags[dp.dwCount] |= (DP_MONTH|DP_DATESEP);
            dp.dwCount++;
          }
          else if (i > 39)
          {
            if (!dp.dwCount || dp.dwParseFlags & (DP_AM|DP_PM))
              hRet = DISP_E_TYPEMISMATCH;
            else
            {
              dp.dwFlags[dp.dwCount - 1] |= (i == 40 ? DP_AM : DP_PM);
              dp.dwParseFlags |= (i == 40 ? DP_AM : DP_PM);
            }
          }
          strIn += (dwLen - 1);
          bFound = TRUE;
          break;
        }
      }

      if (!bFound)
      {
        if ((*strIn == 'a' || *strIn == 'A' || *strIn == 'p' || *strIn == 'P') &&
            (dp.dwCount && !(dp.dwParseFlags & (DP_AM|DP_PM))))
        {
          /* Special case - 'a' and 'p' are recognised as short for am/pm */
          if (*strIn == 'a' || *strIn == 'A')
          {
            dp.dwFlags[dp.dwCount - 1] |= DP_AM;
            dp.dwParseFlags |=  DP_AM;
          }
          else
          {
            dp.dwFlags[dp.dwCount - 1] |= DP_PM;
            dp.dwParseFlags |=  DP_PM;
          }
          strIn++;
        }
        else
        {
          TRACE("No matching token for %s\n", debugstr_w(strIn));
          hRet = DISP_E_TYPEMISMATCH;
          break;
        }
      }
    }
    else if (*strIn == ':' ||  *strIn == '.')
    {
      if (!dp.dwCount || !strIn[1])
        hRet = DISP_E_TYPEMISMATCH;
      else
        dp.dwFlags[dp.dwCount - 1] |= DP_TIMESEP;
    }
    else if (*strIn == '-' || *strIn == '/')
    {
      dwDateSeps++;
      if (dwDateSeps > 2 || !dp.dwCount || !strIn[1])
        hRet = DISP_E_TYPEMISMATCH;
      else
        dp.dwFlags[dp.dwCount - 1] |= DP_DATESEP;
    }
    else if (*strIn == ',' || isspaceW(*strIn))
    {
      if (*strIn == ',' && !strIn[1])
        hRet = DISP_E_TYPEMISMATCH;
    }
    else
    {
      hRet = DISP_E_TYPEMISMATCH;
    }
    strIn++;
  }

  if (!dp.dwCount || dp.dwCount > 6 ||
      (dp.dwCount == 1 && !(dp.dwParseFlags & (DP_AM|DP_PM))))
    hRet = DISP_E_TYPEMISMATCH;

  if (SUCCEEDED(hRet))
  {
    SYSTEMTIME st;
    DWORD dwOffset = 0; /* Start of date fields in dp.dwValues */

    st.wDayOfWeek = st.wHour = st.wMinute = st.wSecond = st.wMilliseconds = 0;

    /* Figure out which numbers correspond to which fields.
     *
     * This switch statement works based on the fact that native interprets any
     * fields that are not joined with a time separator ('.' or ':') as date
     * fields. Thus we construct a value from 0-32 where each set bit indicates
     * a time field. This encapsulates the hundreds of permutations of 2-6 fields.
     * For valid permutations, we set dwOffset to point to the first date field
     * and shorten dp.dwCount by the number of time fields found. The real
     * magic here occurs in VARIANT_MakeDate() above, where we determine what
     * each date number must represent in the context of iDate.
     */
    TRACE("0x%08lx\n", TIMEFLAG(0)|TIMEFLAG(1)|TIMEFLAG(2)|TIMEFLAG(3)|TIMEFLAG(4));

    switch (TIMEFLAG(0)|TIMEFLAG(1)|TIMEFLAG(2)|TIMEFLAG(3)|TIMEFLAG(4))
    {
    case 0x1: /* TT TTDD TTDDD */
      if (dp.dwCount > 3 &&
          ((dp.dwFlags[2] & (DP_AM|DP_PM)) || (dp.dwFlags[3] & (DP_AM|DP_PM)) ||
          (dp.dwFlags[4] & (DP_AM|DP_PM))))
        hRet = DISP_E_TYPEMISMATCH;
      else if (dp.dwCount != 2 && dp.dwCount != 4 && dp.dwCount != 5)
        hRet = DISP_E_TYPEMISMATCH;
      st.wHour = dp.dwValues[0];
      st.wMinute  = dp.dwValues[1];
      dp.dwCount -= 2;
      dwOffset = 2;
      break;

    case 0x3: /* TTT TTTDD TTTDDD */
      if (dp.dwCount > 4 &&
          ((dp.dwFlags[3] & (DP_AM|DP_PM)) || (dp.dwFlags[4] & (DP_AM|DP_PM)) ||
          (dp.dwFlags[5] & (DP_AM|DP_PM))))
        hRet = DISP_E_TYPEMISMATCH;
      else if (dp.dwCount != 3 && dp.dwCount != 5 && dp.dwCount != 6)
        hRet = DISP_E_TYPEMISMATCH;
      st.wHour   = dp.dwValues[0];
      st.wMinute = dp.dwValues[1];
      st.wSecond = dp.dwValues[2];
      dwOffset = 3;
      dp.dwCount -= 3;
      break;

    case 0x4: /* DDTT */
      if (dp.dwCount != 4 ||
          (dp.dwFlags[0] & (DP_AM|DP_PM)) || (dp.dwFlags[1] & (DP_AM|DP_PM)))
        hRet = DISP_E_TYPEMISMATCH;

      st.wHour = dp.dwValues[2];
      st.wMinute  = dp.dwValues[3];
      dp.dwCount -= 2;
      break;

   case 0x0: /* T DD DDD TDDD TDDD */
      if (dp.dwCount == 1 && (dp.dwParseFlags & (DP_AM|DP_PM)))
      {
        st.wHour = dp.dwValues[0]; /* T */
        dp.dwCount = 0;
        break;
      }
      else if (dp.dwCount > 4 || (dp.dwCount < 3 && dp.dwParseFlags & (DP_AM|DP_PM)))
      {
        hRet = DISP_E_TYPEMISMATCH;
      }
      else if (dp.dwCount == 3)
      {
        if (dp.dwFlags[0] & (DP_AM|DP_PM)) /* TDD */
        {
          dp.dwCount = 2;
          st.wHour = dp.dwValues[0];
          dwOffset = 1;
          break;
        }
        if (dp.dwFlags[2] & (DP_AM|DP_PM)) /* DDT */
        {
          dp.dwCount = 2;
          st.wHour = dp.dwValues[2];
          break;
        }
        else if (dp.dwParseFlags & (DP_AM|DP_PM))
          hRet = DISP_E_TYPEMISMATCH;
      }
      else if (dp.dwCount == 4)
      {
        dp.dwCount = 3;
        if (dp.dwFlags[0] & (DP_AM|DP_PM)) /* TDDD */
        {
          st.wHour = dp.dwValues[0];
          dwOffset = 1;
        }
        else if (dp.dwFlags[3] & (DP_AM|DP_PM)) /* DDDT */
        {
          st.wHour = dp.dwValues[3];
        }
        else
          hRet = DISP_E_TYPEMISMATCH;
        break;
      }
      /* .. fall through .. */

    case 0x8: /* DDDTT */
      if ((dp.dwCount == 2 && (dp.dwParseFlags & (DP_AM|DP_PM))) ||
          (dp.dwCount == 5 && ((dp.dwFlags[0] & (DP_AM|DP_PM)) ||
           (dp.dwFlags[1] & (DP_AM|DP_PM)) || (dp.dwFlags[2] & (DP_AM|DP_PM)))) ||
           dp.dwCount == 4 || dp.dwCount == 6)
        hRet = DISP_E_TYPEMISMATCH;
      st.wHour   = dp.dwValues[3];
      st.wMinute = dp.dwValues[4];
      if (dp.dwCount == 5)
        dp.dwCount -= 2;
      break;

    case 0xC: /* DDTTT */
      if (dp.dwCount != 5 ||
          (dp.dwFlags[0] & (DP_AM|DP_PM)) || (dp.dwFlags[1] & (DP_AM|DP_PM)))
        hRet = DISP_E_TYPEMISMATCH;
      st.wHour   = dp.dwValues[2];
      st.wMinute = dp.dwValues[3];
      st.wSecond = dp.dwValues[4];
      dp.dwCount -= 3;
      break;

    case 0x18: /* DDDTTT */
      if ((dp.dwFlags[0] & (DP_AM|DP_PM)) || (dp.dwFlags[1] & (DP_AM|DP_PM)) ||
          (dp.dwFlags[2] & (DP_AM|DP_PM)))
        hRet = DISP_E_TYPEMISMATCH;
      st.wHour   = dp.dwValues[3];
      st.wMinute = dp.dwValues[4];
      st.wSecond = dp.dwValues[5];
      dp.dwCount -= 3;
      break;

    default:
      hRet = DISP_E_TYPEMISMATCH;
      break;
    }

    if (SUCCEEDED(hRet))
    {
      hRet = VARIANT_MakeDate(&dp, iDate, dwOffset, &st);

      if (dwFlags & VAR_TIMEVALUEONLY)
      {
        st.wYear = 1899;
        st.wMonth = 12;
        st.wDay = 30;
      }
      else if (dwFlags & VAR_DATEVALUEONLY)
       st.wHour = st.wMinute = st.wSecond = 0;

      /* Finally, convert the value to a VT_DATE */
      if (SUCCEEDED(hRet))
        hRet = SystemTimeToVariantTime(&st, pdateOut) ? S_OK : DISP_E_TYPEMISMATCH;
    }
  }

  for (i = 0; i < sizeof(tokens)/sizeof(tokens[0]); i++)
    SysFreeString(tokens[i]);
  return hRet;
}

/******************************************************************************
 * VarDateFromI1 (OLEAUT32.221)
 *
 * Convert a VT_I1 to a VT_DATE.
 *
 * PARAMS
 *  cIn      [I] Source
 *  pdateOut [O] Destination
 *
 * RETURNS
 *  S_OK.
 */
HRESULT WINAPI VarDateFromI1(signed char cIn, DATE* pdateOut)
{
  return VarR8FromI1(cIn, pdateOut);
}

/******************************************************************************
 * VarDateFromUI2 (OLEAUT32.222)
 *
 * Convert a VT_UI2 to a VT_DATE.
 *
 * PARAMS
 *  uiIn     [I] Source
 *  pdateOut [O] Destination
 *
 * RETURNS
 *  S_OK.
 */
HRESULT WINAPI VarDateFromUI2(USHORT uiIn, DATE* pdateOut)
{
  return VarR8FromUI2(uiIn, pdateOut);
}

/******************************************************************************
 * VarDateFromUI4 (OLEAUT32.223)
 *
 * Convert a VT_UI4 to a VT_DATE.
 *
 * PARAMS
 *  ulIn     [I] Source
 *  pdateOut [O] Destination
 *
 * RETURNS
 *  S_OK.
 */
HRESULT WINAPI VarDateFromUI4(ULONG ulIn, DATE* pdateOut)
{
  return VarDateFromR8(ulIn, pdateOut);
}

/**********************************************************************
 * VarDateFromDec (OLEAUT32.224)
 *
 * Convert a VT_DECIMAL to a VT_DATE.
 *
 * PARAMS
 *  pdecIn   [I] Source
 *  pdateOut [O] Destination
 *
 * RETURNS
 *  S_OK.
 */
HRESULT WINAPI VarDateFromDec(DECIMAL *pdecIn, DATE* pdateOut)
{
  return VarR8FromDec(pdecIn, pdateOut);
}

/******************************************************************************
 * VarDateFromI8 (OLEAUT32.364)
 *
 * Convert a VT_I8 to a VT_DATE.
 *
 * PARAMS
 *  llIn     [I] Source
 *  pdateOut [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
 */
HRESULT WINAPI VarDateFromI8(LONG64 llIn, DATE* pdateOut)
{
  if (llIn < DATE_MIN || llIn > DATE_MAX) return DISP_E_OVERFLOW;
  *pdateOut = (DATE)llIn;
  return S_OK;
}

/******************************************************************************
 * VarDateFromUI8 (OLEAUT32.365)
 *
 * Convert a VT_UI8 to a VT_DATE.
 *
 * PARAMS
 *  ullIn    [I] Source
 *  pdateOut [O] Destination
 *
 * RETURNS
 *  Success: S_OK.
 *  Failure: DISP_E_OVERFLOW, if the value will not fit in the destination
 */
HRESULT WINAPI VarDateFromUI8(ULONG64 ullIn, DATE* pdateOut)
{
  if (ullIn > DATE_MAX) return DISP_E_OVERFLOW;
  *pdateOut = (DATE)ullIn;
  return S_OK;
}
