Cheers,
Jon
License: X11
ChangeLog:
Jon Griffiths <jon_p_griffiths@xxxxxxxxx>
+include/oleauto.h
Add some missing prototype/defines.
+dlls/oleaut32/oleaut.c
OaBuildVersion() returns a ULONG, not UINT
+dlls/oleaut32/variant.c
Implement the non-variant date conversions correctly, without
going
through 'struct tm' first. Handle negative & 'rolling' dates too.
__________________________________
Do you Yahoo!?
Protect your identity with Yahoo! Mail AddressGuard
http://antispam.yahoo.com/whatsnewfree
--- wine/include/oleauto.h 2003-09-11 16:11:34.000000000 +0000
+++ wine-develop/include/oleauto.h 2003-11-14 22:29:28.000000000 +0000
@@ -27,10 +27,17 @@
DEFINE_OLEGUID(IID_StdOle, 0x00020430,0,0);
-/*
- * BSTR API
- */
+#define STDOLE_MAJORVERNUM 1
+#define STDOLE_MINORVERNUM 0
+#define STDOLE_LCID 0
+
+#define STDOLE2_MAJORVERNUM 2
+#define STDOLE2_MINORVERNUM 0
+#define STDOLE2_LCID 0
+
+ULONG WINAPI OaBuildVersion(void);
+/* BSTR functions */
BSTR WINAPI SysAllocString(const OLECHAR*);
BSTR WINAPI SysAllocStringByteLen(LPCSTR,UINT);
BSTR WINAPI SysAllocStringLen(const OLECHAR*,UINT);
@@ -40,19 +47,12 @@
int WINAPI SysStringByteLen(BSTR);
int WINAPI SysStringLen(BSTR);
-
-/*****************************************************************
- * ErrorInfo API
- */
-
+/* IErrorInfo helpers */
HRESULT WINAPI SetErrorInfo(ULONG,IErrorInfo*);
HRESULT WINAPI GetErrorInfo(ULONG,IErrorInfo**);
HRESULT WINAPI CreateErrorInfo(ICreateErrorInfo**);
-/*****************************************************************
- * SafeArray API
- */
-
+/* SafeArray functions */
SAFEARRAY* WINAPI SafeArrayCreate(VARTYPE,UINT,SAFEARRAYBOUND*);
SAFEARRAY* WINAPI SafeArrayCreateEx(VARTYPE,UINT,SAFEARRAYBOUND*,LPVOID);
SAFEARRAY* WINAPI SafeArrayCreateVector(VARTYPE,LONG,ULONG);
@@ -84,73 +84,101 @@
HRESULT WINAPI SafeArraySetIID(SAFEARRAY*,REFGUID);
HRESULT WINAPI SafeArrayGetIID(SAFEARRAY*,GUID*);
-/* These are macros that help accessing the VARIANT date type.
+HRESULT WINAPI VectorFromBstr(BSTR,SAFEARRAY**);
+HRESULT WINAPI BstrFromVector(SAFEARRAY*,BSTR*);
+
+/* Object registration helpers */
+#define ACTIVEOBJECT_STRONG 0
+#define ACTIVEOBJECT_WEAK 1
+
+HRESULT WINAPI RegisterActiveObject(LPUNKNOWN,REFCLSID,DWORD,LPDWORD);
+HRESULT WINAPI RevokeActiveObject(DWORD,LPVOID);
+HRESULT WINAPI GetActiveObject(REFCLSID,LPVOID,LPUNKNOWN*);
+
+/* IRecordInfo helpers */
+HRESULT WINAPI GetRecordInfoFromTypeInfo(ITypeInfo*,IRecordInfo**);
+HRESULT WINAPI GetRecordInfoFromGuids(REFGUID,ULONG,ULONG,LCID,REFGUID,IRecordInfo**);
+
+/*
+ * Variants
*/
+
+/* Macros for accessing the fields of the VARIANT type */
#if (__STDC__ && !defined(_FORCENAMELESSUNION)) || defined(NONAMELESSUNION)
-#define V_UNION(A, B) ((A)->n1.n2.n3.B)
-#define V_VT(A) ((A)->n1.n2.vt)
+#define V_UNION(A,B) ((A)->n1.n2.n3.B)
+#define V_VT(A) ((A)->n1.n2.vt)
#else
-#define V_UNION(A, B) ((A)->B)
-#define V_VT(A) ((A)->vt)
-#endif /* cplusplus */
+#define V_UNION(A,B) ((A)->B)
+#define V_VT(A) ((A)->vt)
+#endif
-#define V_ISBYREF(A) (V_VT(A)&VT_BYREF)
-#define V_ISARRAY(A) (V_VT(A)&VT_ARRAY)
-#define V_ISVECTOR(A) (V_VT(A)&VT_VECTOR)
-#define V_NONE(A) V_I2(A)
+#define V_ISBYREF(A) (V_VT(A) & VT_BYREF)
+#define V_ISARRAY(A) (V_VT(A) & VT_ARRAY)
+#define V_ISVECTOR(A) (V_VT(A) & VT_VECTOR)
+#define V_NONE(A) V_I2(A)
-#define V_UI1(A) V_UNION(A, bVal)
-#define V_UI1REF(A) V_UNION(A, pbVal)
-#define V_I2(A) V_UNION(A, iVal)
-#define V_I2REF(A) V_UNION(A, piVal)
-#define V_I4(A) V_UNION(A, lVal)
-#define V_I4REF(A) V_UNION(A, plVal)
-#define V_R4(A) V_UNION(A, fltVal)
-#define V_R4REF(A) V_UNION(A, pfltVal)
-#define V_R8(A) V_UNION(A, dblVal)
-#define V_R8REF(A) V_UNION(A, pdblVal)
-#define V_I1(A) V_UNION(A, cVal)
-#define V_I1REF(A) V_UNION(A, pcVal)
-#define V_UI2(A) V_UNION(A, uiVal)
-#define V_UI2REF(A) V_UNION(A, puiVal)
-#define V_UI4(A) V_UNION(A, ulVal)
-#define V_UI4REF(A) V_UNION(A, pulVal)
-#define V_INT(A) V_UNION(A, intVal)
-#define V_INTREF(A) V_UNION(A, pintVal)
-#define V_UINT(A) V_UNION(A, uintVal)
-#define V_UINTREF(A) V_UNION(A, puintVal)
-#define V_I8(A) V_UNION(A, llVal)
-#define V_I8REF(A) V_UNION(A, pllVal)
-#define V_UI8(A) V_UNION(A, ullVal)
-#define V_UI8REF(A) V_UNION(A, pullVal)
-#define V_CY(A) V_UNION(A, cyVal)
-#define V_CYREF(A) V_UNION(A, pcyVal)
-#define V_DATE(A) V_UNION(A, date)
-#define V_DATEREF(A) V_UNION(A, pdate)
-#define V_BSTR(A) V_UNION(A, bstrVal)
-#define V_BSTRREF(A) V_UNION(A, pbstrVal)
-#define V_DISPATCH(A) V_UNION(A, pdispVal)
-#define V_DISPATCHREF(A) V_UNION(A, ppdispVal)
-#define V_ERROR(A) V_UNION(A, scode)
-#define V_ERRORREF(A) V_UNION(A, pscode)
-#define V_BOOL(A) V_UNION(A, boolVal)
-#define V_BOOLREF(A) V_UNION(A, pboolVal)
-#define V_UNKNOWN(A) V_UNION(A, punkVal)
-#define V_UNKNOWNREF(A) V_UNION(A, ppunkVal)
-#define V_VARIANTREF(A) V_UNION(A, pvarVal)
-#define V_ARRAY(A) V_UNION(A, parray)
-#define V_ARRAYREF(A) V_UNION(A, pparray)
-#define V_BYREF(A) V_UNION(A, byref)
-#define V_DECIMALREF(A) V_UNION(A, pdecVal)
+#define V_ARRAY(A) V_UNION(A,parray)
+#define V_ARRAYREF(A) V_UNION(A,pparray)
+#define V_BOOL(A) V_UNION(A,boolVal)
+#define V_BOOLREF(A) V_UNION(A,pboolVal)
+#define V_BSTR(A) V_UNION(A,bstrVal)
+#define V_BSTRREF(A) V_UNION(A,pbstrVal)
+#define V_BYREF(A) V_UNION(A,byref)
+#define V_CY(A) V_UNION(A,cyVal)
+#define V_CYREF(A) V_UNION(A,pcyVal)
+#define V_DATE(A) V_UNION(A,date)
+#define V_DATEREF(A) V_UNION(A,pdate)
#if (__STDC__ && !defined(_FORCENAMELESSUNION)) || defined(NONAMELESSUNION)
-#define V_DECIMAL(A) ((A)->n1.decVal)
+#define V_DECIMAL(A) ((A)->n1.decVal)
#else
-#define V_DECIMAL(A) ((A)->decVal)
+#define V_DECIMAL(A) ((A)->decVal)
#endif
-
-/*
- * VARIANT API
- */
+#define V_DECIMALREF(A) V_UNION(A,pdecVal)
+#define V_DISPATCH(A) V_UNION(A,pdispVal)
+#define V_DISPATCHREF(A) V_UNION(A,ppdispVal)
+#define V_ERROR(A) V_UNION(A,scode)
+#define V_ERRORREF(A) V_UNION(A,pscode)
+#define V_I1(A) V_UNION(A,cVal)
+#define V_I1REF(A) V_UNION(A,pcVal)
+#define V_I2(A) V_UNION(A,iVal)
+#define V_I2REF(A) V_UNION(A,piVal)
+#define V_I4(A) V_UNION(A,lVal)
+#define V_I4REF(A) V_UNION(A,plVal)
+#define V_I8(A) V_UNION(A,llVal)
+#define V_I8REF(A) V_UNION(A,pllVal)
+#define V_INT(A) V_UNION(A,intVal)
+#define V_INTREF(A) V_UNION(A,pintVal)
+#ifdef _WIN64
+#define V_INT_PTR(A) V_I8(A)
+#define V_INT_PTRREF(A) V_I8REF(A)
+#else
+#define V_INT_PTR(A) V_I4(A)
+#define V_INT_PTRREF(A) V_I4REF(A)
+#endif
+#define V_R4(A) V_UNION(A,fltVal)
+#define V_R4REF(A) V_UNION(A,pfltVal)
+#define V_R8(A) V_UNION(A,dblVal)
+#define V_R8REF(A) V_UNION(A,pdblVal)
+#define V_UINT(A) V_UNION(A,uintVal)
+#define V_UINTREF(A) V_UNION(A,puintVal)
+#define V_UI1(A) V_UNION(A,bVal)
+#define V_UI1REF(A) V_UNION(A,pbVal)
+#define V_UI2(A) V_UNION(A,uiVal)
+#define V_UI2REF(A) V_UNION(A,puiVal)
+#define V_UI4(A) V_UNION(A,ulVal)
+#define V_UI4REF(A) V_UNION(A,pulVal)
+#define V_UI8(A) V_UNION(A,ullVal)
+#define V_UI8REF(A) V_UNION(A,pullVal)
+#ifdef _WIN64
+#define V_UINT_PTR(A) V_UI8(A)
+#define V_UINT_PTRREF(A) V_UI8REF(A)
+#else
+#define V_UINT_PTR(A) V_UI4(A)
+#define V_UINT_PTRREF(A) V_UI4REF(A)
+#endif
+#define V_UNKNOWN(A) V_UNION(A,punkVal)
+#define V_UNKNOWNREF(A) V_UNION(A,ppunkVal)
+#define V_VARIANTREF(A) V_UNION(A,pvarVal)
void WINAPI VariantInit(VARIANT*);
HRESULT WINAPI VariantClear(VARIANT*);
@@ -159,62 +187,40 @@
HRESULT WINAPI VariantChangeType(VARIANT*,VARIANT*,USHORT,VARTYPE);
HRESULT WINAPI VariantChangeTypeEx(VARIANT*,VARIANT*,LCID,USHORT,VARTYPE);
-/*
- * These flags are used for the VariantChangeType and VariantChangeTypeEx APIs.
- */
-
-/*
- * This one is of general use.
- */
-#define VARIANT_NOVALUEPROP 0x1
-/*
- * This one is used for conversions of VT_BOOL to VT_BSTR,
- * the API will convert to "True"|"False" instead of "-1"|"0".
- */
-#define VARIANT_ALPHABOOL 0x2
-/*
- * This one is used for conversions to or from a VT_BSTR string,
- * it passes LOCALE_NOUSEROVERRIDE to the core (low-level) coercion routines.
- * This means it will use the system default locale settings instead of custom
- * local settings.
- */
-#define VARIANT_NOUSEROVERRIDE 0x4
-
-/*
- * This one is used for conversions of VT_BOOL to VT_BSTR,
- * Convert to the localised text of "True"|"False" instead of "-1"|"0".
- */
-#define VARIANT_LOCALBOOL 0x10
-
-/*
- * Alternate calendar support.
- */
-#define VARIANT_CALENDAR_HIJRI 0x08
-#define VARIANT_CALENDAR_THAI 0x20
-#define VARIANT_CALENDAR_GREGORIAN 0x40
+/* VariantChangeType/VariantChangeTypeEx flags */
+#define VARIANT_NOVALUEPROP 0x01 /* Don't get the default value property from IDispatch */
+#define VARIANT_ALPHABOOL 0x02 /* Coerce to "True"|"False" instead of "-1"|"0" */
+#define VARIANT_NOUSEROVERRIDE 0x04 /* Pass LOCALE_NOUSEROVERRIDE to low level conversions */
+#define VARIANT_CALENDAR_HIJRI 0x08 /* Use the Hijri calendar */
+#define VARIANT_LOCALBOOL 0x10 /* Like VARIANT_ALPHABOOL, but use localised text */
+#define VARIANT_CALENDAR_THAI 0x20 /* Use the Thai buddhist calendar */
+#define VARIANT_CALENDAR_GREGORIAN 0x40 /* Use the Gregorian calendar */
+#define VARIANT_USE_NLS 0x80 /* Format result using NLS calls */
/*
- * Use NLS calls in conversion
+ * Low level Variant coercion functions
*/
-#define VARIANT_USE_NLS 0x80
-/*
- * Convert between SafeArray vectors and BSTR's
- */
-HRESULT WINAPI VectorFromBstr(BSTR,SAFEARRAY**);
-HRESULT WINAPI BstrFromVector(SAFEARRAY*,BSTR*);
+#define VT_HARDTYPE VT_RESERVED /* Don't coerce this variant when comparing it to others */
-/*
- * VARTYPE Coercion API
- */
+/* Flags for low level coercions. LOCALE_ flags can also be passed */
+#define VAR_TIMEVALUEONLY 0x001 /* Ignore date portion of VT_DATE */
+#define VAR_DATEVALUEONLY 0x002 /* Ignore time portion of VT_DATE */
+#define VAR_VALIDDATE 0x004
+#define VAR_CALENDAR_HIJRI 0x008 /* Use the Hijri calender */
+#define VAR_LOCALBOOL 0x010 /* VT_BOOL<->VT_BSTR: Use localised boolean text */
+#define VAR_FORMAT_NOSUBSTITUTE 0x020 /* Don't change format strings for un-coercable types */
+#define VAR_FOURDIGITYEARS 0x040 /* Always print years with 4 digits */
+#define VAR_CALENDAR_THAI 0x080 /* Use the Thai buddhist calendar */
+#define VAR_CALENDAR_GREGORIAN 0x100 /* Use the Gregorian calendar */
-/* Omits the date portion and return only the time value.
- */
-#define VAR_TIMEVALUEONLY ((DWORD)0x00000001)
-/* Omits the time portion and return only the date value.
- */
-#define VAR_DATEVALUEONLY ((DWORD)0x00000002)
+#ifndef LOCALE_USE_NLS
+/* This is missing from native winnls.h, but may be added at some point */
+#define LOCALE_USE_NLS 0x10000000
+#endif
+#define VTDATEGRE_MIN -657434 /* Minimum possible Gregorian date: 1/1/100 */
+#define VTDATEGRE_MAX 2958465 /* Maximum possible Gregorian date: 31/12/9999 */
HRESULT WINAPI VarUI1FromI2(SHORT,BYTE*);
HRESULT WINAPI VarUI1FromI4(LONG,BYTE*);
@@ -462,70 +468,70 @@
#define VarUI4FromUI4( in,pOut ) ( *(pOut) = (in) )
#define VarI4FromI4( in,pOut ) ( *(pOut) = (in) )
-#define VarUI1FromInt VarUI1FromI4
-#define VarUI1FromUint VarUI1FromUI4
-#define VarI2FromInt VarI2FromI4
-#define VarI2FromUint VarI2FromUI4
-#define VarI4FromInt VarI4FromI4
-#define VarI4FromUint VarI4FromUI4
-#define VarI8FromInt VarI8FromI4
-#define VarI8FromUint VarI8FromUI4
-#define VarR4FromInt VarR4FromI4
-#define VarR4FromUint VarR4FromUI4
-#define VarR8FromInt VarR8FromI4
-#define VarR8FromUint VarR8FromUI4
-#define VarDateFromInt VarDateFromI4
-#define VarDateFromUint VarDateFromUI4
-#define VarCyFromInt VarCyFromI4
-#define VarCyFromUint VarCyFromUI4
-#define VarBstrFromInt VarBstrFromI4
-#define VarBstrFromUint VarBstrFromUI4
-#define VarBoolFromInt VarBoolFromI4
-#define VarBoolFromUint VarBoolFromUI4
-#define VarI1FromInt VarI1FromI4
-#define VarI1FromUint VarI1FromUI4
-#define VarUI2FromInt VarUI2FromI4
-#define VarUI2FromUint VarUI2FromUI4
-#define VarUI4FromInt VarUI4FromI4
-#define VarUI4FromUint VarUI4FromUI4
-#define VarUI8FromInt VarUI8FromI4
-#define VarUI8FromUint VarUI8FromUI4
-#define VarDecFromInt VarDecFromI4
-#define VarDecFromUint VarDecFromUI4
-#define VarIntFromUI1 VarI4FromUI1
-#define VarIntFromI2 VarI4FromI2
-#define VarIntFromI4 VarI4FromI4
-#define VarIntFromI8 VarI4FromI8
-#define VarIntFromR4 VarI4FromR4
-#define VarIntFromR8 VarI4FromR8
-#define VarIntFromDate VarI4FromDate
-#define VarIntFromCy VarI4FromCy
-#define VarIntFromStr VarI4FromStr
-#define VarIntFromDisp VarI4FromDisp
-#define VarIntFromBool VarI4FromBool
-#define VarIntFromI1 VarI4FromI1
-#define VarIntFromUI2 VarI4FromUI2
-#define VarIntFromUI4 VarI4FromUI4
-#define VarIntFromUI8 VarI4FromUI8
-#define VarIntFromDec VarI4FromDec
-#define VarIntFromUint VarI4FromUI4
-#define VarUintFromUI1 VarUI4FromUI1
-#define VarUintFromI2 VarUI4FromI2
-#define VarUintFromI4 VarUI4FromI4
-#define VarUintFromI8 VarUI4FromI8
-#define VarUintFromR4 VarUI4FromR4
-#define VarUintFromR8 VarUI4FromR8
-#define VarUintFromDate VarUI4FromDate
-#define VarUintFromCy VarUI4FromCy
-#define VarUintFromStr VarUI4FromStr
-#define VarUintFromDisp VarUI4FromDisp
-#define VarUintFromBool VarUI4FromBool
-#define VarUintFromI1 VarUI4FromI1
-#define VarUintFromUI2 VarUI4FromUI2
-#define VarUintFromUI4 VarUI4FromUI4
-#define VarUintFromUI8 VarUI4FromUI8
-#define VarUintFromDec VarUI4FromDec
-#define VarUintFromInt VarUI4FromI4
+#define VarUI1FromInt VarUI1FromI4
+#define VarUI1FromUint VarUI1FromUI4
+#define VarI2FromInt VarI2FromI4
+#define VarI2FromUint VarI2FromUI4
+#define VarI4FromInt VarI4FromI4
+#define VarI4FromUint VarI4FromUI4
+#define VarI8FromInt VarI8FromI4
+#define VarI8FromUint VarI8FromUI4
+#define VarR4FromInt VarR4FromI4
+#define VarR4FromUint VarR4FromUI4
+#define VarR8FromInt VarR8FromI4
+#define VarR8FromUint VarR8FromUI4
+#define VarDateFromInt VarDateFromI4
+#define VarDateFromUint VarDateFromUI4
+#define VarCyFromInt VarCyFromI4
+#define VarCyFromUint VarCyFromUI4
+#define VarBstrFromInt VarBstrFromI4
+#define VarBstrFromUint VarBstrFromUI4
+#define VarBoolFromInt VarBoolFromI4
+#define VarBoolFromUint VarBoolFromUI4
+#define VarI1FromInt VarI1FromI4
+#define VarI1FromUint VarI1FromUI4
+#define VarUI2FromInt VarUI2FromI4
+#define VarUI2FromUint VarUI2FromUI4
+#define VarUI4FromInt VarUI4FromI4
+#define VarUI4FromUint VarUI4FromUI4
+#define VarUI8FromInt VarUI8FromI4
+#define VarUI8FromUint VarUI8FromUI4
+#define VarDecFromInt VarDecFromI4
+#define VarDecFromUint VarDecFromUI4
+#define VarIntFromUI1 VarI4FromUI1
+#define VarIntFromI2 VarI4FromI2
+#define VarIntFromI4 VarI4FromI4
+#define VarIntFromI8 VarI4FromI8
+#define VarIntFromR4 VarI4FromR4
+#define VarIntFromR8 VarI4FromR8
+#define VarIntFromDate VarI4FromDate
+#define VarIntFromCy VarI4FromCy
+#define VarIntFromStr VarI4FromStr
+#define VarIntFromDisp VarI4FromDisp
+#define VarIntFromBool VarI4FromBool
+#define VarIntFromI1 VarI4FromI1
+#define VarIntFromUI2 VarI4FromUI2
+#define VarIntFromUI4 VarI4FromUI4
+#define VarIntFromUI8 VarI4FromUI8
+#define VarIntFromDec VarI4FromDec
+#define VarIntFromUint VarI4FromUI4
+#define VarUintFromUI1 VarUI4FromUI1
+#define VarUintFromI2 VarUI4FromI2
+#define VarUintFromI4 VarUI4FromI4
+#define VarUintFromI8 VarUI4FromI8
+#define VarUintFromR4 VarUI4FromR4
+#define VarUintFromR8 VarUI4FromR8
+#define VarUintFromDate VarUI4FromDate
+#define VarUintFromCy VarUI4FromCy
+#define VarUintFromStr VarUI4FromStr
+#define VarUintFromDisp VarUI4FromDisp
+#define VarUintFromBool VarUI4FromBool
+#define VarUintFromI1 VarUI4FromI1
+#define VarUintFromUI2 VarUI4FromUI2
+#define VarUintFromUI4 VarUI4FromUI4
+#define VarUintFromUI8 VarUI4FromUI8
+#define VarUintFromDec VarUI4FromDec
+#define VarUintFromInt VarUI4FromI4
/*
* Variant Math operations
@@ -535,6 +541,11 @@
#define VARCMP_GT 2
#define VARCMP_NULL 3
+HRESULT WINAPI VarR4CmpR8(float,double);
+
+HRESULT WINAPI VarR8Pow(double,double,double*);
+HRESULT WINAPI VarR8Round(double,int,double*);
+
HRESULT WINAPI VarDecAbs(const DECIMAL*,DECIMAL*);
HRESULT WINAPI VarDecAdd(const DECIMAL*,const DECIMAL*,DECIMAL*);
HRESULT WINAPI VarDecCmp(const DECIMAL*,const DECIMAL*);
@@ -584,95 +595,120 @@
HRESULT WINAPI VarCmp(LPVARIANT,LPVARIANT,LCID,ULONG);
+HRESULT WINAPI VarBstrCmp(BSTR,BSTR,LCID,ULONG);
+HRESULT WINAPI VarBstrCat(BSTR,BSTR,BSTR*);
-typedef struct tagPARAMDATA {
- OLECHAR * szName; /* parameter name */
- VARTYPE vt; /* parameter type */
-} PARAMDATA, * LPPARAMDATA;
-
-typedef struct tagMETHODDATA {
- OLECHAR * szName; /* method name */
- PARAMDATA * ppdata; /* pointer to an array of PARAMDATAs */
- DISPID dispid; /* method ID */
- UINT iMeth; /* method index */
- CALLCONV cc; /* calling convention */
- UINT cArgs; /* count of arguments */
- WORD wFlags; /* same wFlags as on IDispatch::Invoke() */
- VARTYPE vtReturn;
-} METHODDATA, * LPMETHODDATA;
-
-typedef struct tagINTERFACEDATA {
- METHODDATA * pmethdata; /* pointer to an array of METHODDATAs */
- UINT cMembers; /* count of members */
-} INTERFACEDATA, * LPINTERFACEDATA;
-
-typedef enum tagREGKIND
-{
- REGKIND_DEFAULT,
- REGKIND_REGISTER,
- REGKIND_NONE
-} REGKIND;
-
typedef struct {
SYSTEMTIME st;
USHORT wDayOfYear;
} UDATE;
-typedef struct {
- INT cDig;
- ULONG dwInFlags;
- ULONG dwOutFlags;
- INT cchUsed;
- INT nBaseShift;
- INT nPwr10;
+typedef struct
+{
+ INT cDig; /* Number of parsed digits */
+ ULONG dwInFlags; /* Acceptable state of the input string (NUMPRS_ flags) */
+ ULONG dwOutFlags; /* Parsed state of the output string (NUMPRS_ flags) */
+ INT cchUsed; /* Number of characters parsed from input string */
+ INT nBaseShift; /* Base of the number (but apparently unused) */
+ INT nPwr10; /* Scale of the number in powers of 10 */
} NUMPARSE;
-#define NUMPRS_LEADING_WHITE 0x0001
-#define NUMPRS_TRAILING_WHITE 0x0002
-#define NUMPRS_LEADING_PLUS 0x0004
-#define NUMPRS_TRAILING_PLUS 0x0008
-#define NUMPRS_LEADING_MINUS 0x0010
-#define NUMPRS_TRAILING_MINUS 0x0020
-#define NUMPRS_HEX_OCT 0x0040
-#define NUMPRS_PARENS 0x0080
-#define NUMPRS_DECIMAL 0x0100
-#define NUMPRS_THOUSANDS 0x0200
-#define NUMPRS_CURRENCY 0x0400
-#define NUMPRS_EXPONENT 0x0800
-#define NUMPRS_USE_ALL 0x1000
-#define NUMPRS_STD 0x1FFF
-
-#define NUMPRS_NEG 0x10000
-#define NUMPRS_INEXACT 0x20000
+#define NUMPRS_LEADING_WHITE 0x00001 /* Leading whitespace */
+#define NUMPRS_TRAILING_WHITE 0x00002 /* Trailing whitespace */
+#define NUMPRS_LEADING_PLUS 0x00004 /* Leading '+' sign */
+#define NUMPRS_TRAILING_PLUS 0x00008 /* Trailing '+' sign */
+#define NUMPRS_LEADING_MINUS 0x00010 /* Leading '-' sign */
+#define NUMPRS_TRAILING_MINUS 0x00020 /* Trailing '-' sign */
+#define NUMPRS_HEX_OCT 0x00040 /* Octal number (with a leading 0) */
+#define NUMPRS_PARENS 0x00080 /* Parentheses for negative numbers */
+#define NUMPRS_DECIMAL 0x00100 /* Decimal seperator */
+#define NUMPRS_THOUSANDS 0x00200 /* Thousands seperator */
+#define NUMPRS_CURRENCY 0x00400 /* Currency symbol */
+#define NUMPRS_EXPONENT 0x00800 /* Exponent (e.g. "e-14") */
+#define NUMPRS_USE_ALL 0x01000 /* Parse the entire string */
+#define NUMPRS_STD 0x01FFF /* Standard flags for internal coercions (All of the above) */
+#define NUMPRS_NEG 0x10000 /* Number is negative (dwOutFlags only) */
+#define NUMPRS_INEXACT 0x20000 /* Number is represented inexactly (dwOutFlags only) */
-#define VTBIT_I1 (1 << VT_I1)
-#define VTBIT_UI1 (1 << VT_UI1)
-#define VTBIT_I2 (1 << VT_I2)
-#define VTBIT_UI2 (1 << VT_UI2)
-#define VTBIT_I4 (1 << VT_I4)
-#define VTBIT_UI4 (1 << VT_UI4)
-#define VTBIT_I8 (1 << VT_I8)
-#define VTBIT_UI8 (1 << VT_UI8)
-#define VTBIT_R4 (1 << VT_R4)
-#define VTBIT_R8 (1 << VT_R8)
-#define VTBIT_CY (1 << VT_CY)
-#define VTBIT_DECIMAL (1 << VT_DECIMAL)
+#define VTBIT_I1 (1 << VT_I1)
+#define VTBIT_UI1 (1 << VT_UI1)
+#define VTBIT_I2 (1 << VT_I2)
+#define VTBIT_UI2 (1 << VT_UI2)
+#define VTBIT_I4 (1 << VT_I4)
+#define VTBIT_UI4 (1 << VT_UI4)
+#define VTBIT_I8 (1 << VT_I8)
+#define VTBIT_UI8 (1 << VT_UI8)
+#define VTBIT_R4 (1 << VT_R4)
+#define VTBIT_R8 (1 << VT_R8)
+#define VTBIT_CY (1 << VT_CY)
+#define VTBIT_DECIMAL (1 << VT_DECIMAL)
HRESULT WINAPI VarParseNumFromStr(OLECHAR*,LCID,ULONG,NUMPARSE*,BYTE*);
HRESULT WINAPI VarNumFromParseNum(NUMPARSE*,BYTE*,ULONG,VARIANT*);
-INT WINAPI DosDateTimeToVariantTime(USHORT,USHORT,DATE*);
-INT WINAPI VariantTimeToDosDateTime(DATE,USHORT*,USHORT*);
+INT WINAPI DosDateTimeToVariantTime(USHORT,USHORT,double*);
+INT WINAPI VariantTimeToDosDateTime(double,USHORT*,USHORT*);
-HRESULT WINAPI VariantTimeToSystemTime(DOUBLE,LPSYSTEMTIME);
-HRESULT WINAPI SystemTimeToVariantTime(LPSYSTEMTIME,double*);
+INT WINAPI VariantTimeToSystemTime(DOUBLE,LPSYSTEMTIME);
+INT WINAPI SystemTimeToVariantTime(LPSYSTEMTIME,double*);
HRESULT WINAPI VarDateFromUdate(UDATE*,ULONG,DATE*);
+HRESULT WINAPI VarDateFromUdateEx(UDATE*,LCID,ULONG,DATE*);
HRESULT WINAPI VarUdateFromDate(DATE,ULONG,UDATE*);
-ULONG WINAPI LHashValOfNameSysA(SYSKIND,LCID,LPCSTR);
-ULONG WINAPI LHashValOfNameSys (SYSKIND,LCID,LPCOLESTR);
+/* Variant formatting */
+HRESULT WINAPI VarWeekdayName(int,int,int,ULONG,BSTR*);
+HRESULT WINAPI VarMonthName(int,int,ULONG,BSTR*);
+HRESULT WINAPI GetAltMonthNames(LCID,LPOLESTR**);
+
+HRESULT WINAPI VarFormat(LPVARIANT,LPOLESTR,int,int,ULONG,BSTR*);
+HRESULT WINAPI VarFormatCurrency(LPVARIANT,int,int,int,int,ULONG,BSTR*);
+HRESULT WINAPI VarFormatDateTime(LPVARIANT,int,ULONG,BSTR*);
+HRESULT WINAPI VarFormatNumber(LPVARIANT,int,int,int,int,ULONG,BSTR*);
+HRESULT WINAPI VarFormatPercent(LPVARIANT,int,int,int,int,ULONG,BSTR*);
+
+HRESULT WINAPI VarFormatFromTokens(LPVARIANT,LPOLESTR,LPBYTE,ULONG,BSTR*,LCID);
+HRESULT WINAPI VarTokenizeFormatString(LPOLESTR,LPBYTE,int,int,int,LCID,int*);
+
+
+/*
+ * IDispatch types and helper functions
+ */
+
+/* A structure describing a single parameter to a com object method. */
+typedef struct tagPARAMDATA
+{
+ OLECHAR *szName; /* Name of Parameter */
+ VARTYPE vt; /* Type of Parameter */
+} PARAMDATA, *LPPARAMDATA;
+
+/* A structure describing a single method of a com object. */
+typedef struct tagMETHODDATA
+{
+ OLECHAR *szName; /* Name of method */
+ PARAMDATA *ppdata; /* Parameters of the method */
+ DISPID dispid; /* Id of the method */
+ UINT iMeth; /* Vtable index of the method */
+ CALLCONV cc; /* Calling convention of the method */
+ UINT cArgs; /* Number of parameters in the method */
+ WORD wFlags; /* Type of the method (DISPATCH_ flags) */
+ VARTYPE vtReturn; /* Type of the return value */
+} METHODDATA, *LPMETHODDATA;
+
+/* Structure describing a single com object */
+typedef struct tagINTERFACEDATA
+{
+ METHODDATA *pmethdata; /* Methods of the object */
+ UINT cMembers; /* Number of methods in the object */
+} INTERFACEDATA, *LPINTERFACEDATA;
+
+typedef enum tagREGKIND
+{
+ REGKIND_DEFAULT,
+ REGKIND_REGISTER,
+ REGKIND_NONE
+} REGKIND;
HRESULT WINAPI DispGetParam(DISPPARAMS*,UINT,VARTYPE,VARIANT*,UINT*);
HRESULT WINAPI DispGetIDsOfNames(ITypeInfo*,OLECHAR**,UINT,DISPID*);
@@ -689,13 +725,25 @@
* TypeLib API
*/
-#define MEMBERID_NIL DISPID_UNKNOWN
+ULONG WINAPI LHashValOfNameSysA(SYSKIND,LCID,LPCSTR);
+ULONG WINAPI LHashValOfNameSys(SYSKIND,LCID,LPCOLESTR);
+
+#define LHashValOfName(lcid,name) LHashValOfNameSys(SYS_WIN32,lcid,name)
+#define WHashValOfLHashVal(hash) ((USHORT)((hash) & 0xffff))
+#define IsHashValCompatible(hash1,hash2) ((hash1) & 0xff0000 == (hash2) & 0xff0000)
+
+#define MEMBERID_NIL DISPID_UNKNOWN
+#define ID_DEFAULTINST -2
#define DISPATCH_METHOD 0x1
#define DISPATCH_PROPERTYGET 0x2
#define DISPATCH_PROPERTYPUT 0x4
#define DISPATCH_PROPERTYPUTREF 0x8
+#define LOAD_TLB_AS_32BIT 0x20
+#define LOAD_TLB_AS_64BIT 0x40
+#define MASK_TO_RESET_TLB_BITS ~(LOAD_TLB_AS_32BIT|LOAD_TLB_AS_64BIT)
+
HRESULT WINAPI CreateTypeLib(SYSKIND,const OLECHAR*,ICreateTypeLib**);
HRESULT WINAPI CreateTypeLib2(SYSKIND,LPCOLESTR,ICreateTypeLib2**);
HRESULT WINAPI LoadRegTypeLib(REFGUID,WORD,WORD,LCID,ITypeLib**);
@@ -705,6 +753,8 @@
HRESULT WINAPI RegisterTypeLib(ITypeLib*,OLECHAR*,OLECHAR*);
HRESULT WINAPI UnRegisterTypeLib(REFGUID,WORD,WORD,LCID,SYSKIND);
+VOID WINAPI ClearCustData(LPCUSTDATA);
+
#ifdef __cplusplus
} /* extern "C" */
#endif
diff -ur --minimal wine/dlls/oleaut32/oleaut.c wine-develop/dlls/oleaut32/oleaut.c
--- wine/dlls/oleaut32/oleaut.c 2003-10-16 21:20:12.000000000 +0000
+++ wine-develop/dlls/oleaut32/oleaut.c 2003-11-14 22:45:29.000000000 +0000
@@ -550,7 +550,7 @@
* Currently the versions returned are 2.20 for Win3.1, 2.30 for Win95 & NT 3.51,
* and 2.40 for all later versions. The build number is maximum, i.e. 0xffff.
*/
-UINT WINAPI OaBuildVersion()
+ULONG WINAPI OaBuildVersion()
{
switch(GetVersion() & 0x8000ffff) /* mask off build number */
{
diff -ur --minimal wine/dlls/oleaut32/variant.c wine-develop/dlls/oleaut32/variant.c
--- wine/dlls/oleaut32/variant.c 2003-11-14 21:20:54.000000000 +0000
+++ wine-develop/dlls/oleaut32/variant.c 2003-11-15 00:05:57.000000000 +0000
@@ -2,6 +2,10 @@
* VARIANT
*
* Copyright 1998 Jean-Claude Cote
+ * Copyright 2003 Jon Griffiths
+ * The alorithm for conversion from Julian days to day/month/year is based on
+ * that devised by Henry Fliegel, as implemented in PostgreSQL, which is
+ * Copyright 1994-7 Regents of the University of California
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -4206,27 +4210,427 @@
return DISP_E_TYPEMISMATCH;
}
+/* Date Conversions */
+
+#define IsLeapYear(y) (((y % 4) == 0) && (((y % 100) != 0) || ((y % 400) == 0)))
+
+/* Convert a VT_DATE value to a Julian Date */
+static inline int VARIANT_JulianFromDate(int dateIn)
+{
+ int julianDays = dateIn;
+
+ julianDays -= DATE_MIN; /* Convert to + days from 1 Jan 100 AD */
+ julianDays += 1757585; /* Convert to + days from 23 Nov 4713 BC (Julian) */
+ return julianDays;
+}
+
+/* Convert a Julian Date to a VT_DATE value */
+static inline int VARIANT_DateFromJulian(int dateIn)
+{
+ int julianDays = dateIn;
+
+ julianDays -= 1757585; /* Convert to + days from 1 Jan 100 AD */
+ julianDays += DATE_MIN; /* Convert to +/- days from 1 Jan 1899 AD */
+ return julianDays;
+}
+
+/* Convert a Julian date to Day/Month/Year - from PostgreSQL */
+static inline void VARIANT_DMYFromJulian(int jd, USHORT *year, USHORT *month, USHORT *day)
+{
+ int j, i, l, n;
+
+ l = jd + 68569;
+ n = l * 4 / 146097;
+ l -= (n * 146097 + 3) / 4;
+ i = (4000 * (l + 1)) / 1461001;
+ l += 31 - (i * 1461) / 4;
+ j = (l * 80) / 2447;
+ *day = l - (j * 2447) / 80;
+ l = j / 11;
+ *month = (j + 2) - (12 * l);
+ *year = 100 * (n - 49) + i + l;
+}
+
+/* Convert Day/Month/Year to a Julian date - from PostgreSQL */
+static inline double VARIANT_JulianFromDMY(USHORT year, USHORT month, USHORT day)
+{
+ int m12 = (month - 14) / 12;
+
+ return ((1461 * (year + 4800 + m12)) / 4 + (367 * (month - 2 - 12 * m12)) / 12 -
+ (3 * ((year + 4900 + m12) / 100)) / 4 + day - 32075);
+}
+
+/* Macros for accessing DOS format date/time fields */
+#define DOS_YEAR(x) (1980 + (x >> 9))
+#define DOS_MONTH(x) ((x >> 5) & 0xf)
+#define DOS_DAY(x) (x & 0x1f)
+#define DOS_HOUR(x) (x >> 11)
+#define DOS_MINUTE(x) ((x >> 5) & 0x3f)
+#define DOS_SECOND(x) ((x & 0x1f) << 1)
+/* Create a DOS format date/time */
+#define DOS_DATE(d,m,y) (d | (m << 5) | ((y-1980) << 9))
+#define DOS_TIME(h,m,s) ((s >> 1) | (m << 5) | (h << 11))
+
+/* Roll a date forwards or backwards to correct it */
+static HRESULT VARIANT_RollUdate(UDATE *lpUd)
+{
+ static const BYTE days[] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+
+ TRACE("Raw date: %d/%d/%d %d:%d:%d\n", lpUd->st.wDay, lpUd->st.wMonth,
+ lpUd->st.wYear, lpUd->st.wHour, lpUd->st.wMinute, lpUd->st.wSecond);
+
+ /* Years < 100 are treated as 1900 + year */
+ if (lpUd->st.wYear < 100)
+ lpUd->st.wYear += 1900;
+
+ if (!lpUd->st.wMonth)
+ {
+ /* Roll back to December of the previous year */
+ lpUd->st.wMonth = 12;
+ lpUd->st.wYear--;
+ }
+ else while (lpUd->st.wMonth > 12)
+ {
+ /* Roll forward the correct number of months */
+ lpUd->st.wYear++;
+ lpUd->st.wMonth -= 12;
+ }
+
+ if (lpUd->st.wYear > 9999 || lpUd->st.wHour > 23 ||
+ lpUd->st.wMinute > 59 || lpUd->st.wSecond > 59)
+ return E_INVALIDARG; /* Invalid values */
+
+ if (!lpUd->st.wDay)
+ {
+ /* Roll back the date one day */
+ if (lpUd->st.wMonth == 1)
+ {
+ /* Roll back to December 31 of the previous year */
+ lpUd->st.wDay = 31;
+ lpUd->st.wMonth = 12;
+ lpUd->st.wYear--;
+ }
+ else
+ {
+ lpUd->st.wMonth--; /* Previous month */
+ if (lpUd->st.wMonth == 2 && IsLeapYear(lpUd->st.wYear))
+ lpUd->st.wDay = 29; /* Februaury has 29 days on leap years */
+ else
+ lpUd->st.wDay = days[lpUd->st.wMonth]; /* Last day of the month */
+ }
+ }
+ else if (lpUd->st.wDay > 28)
+ {
+ int rollForward = 0;
+
+ /* Possibly need to roll the date forward */
+ if (lpUd->st.wMonth == 2 && IsLeapYear(lpUd->st.wYear))
+ rollForward = lpUd->st.wDay - 29; /* Februaury has 29 days on leap years */
+ else
+ rollForward = lpUd->st.wDay - days[lpUd->st.wMonth];
+
+ if (rollForward > 0)
+ {
+ lpUd->st.wDay = rollForward;
+ lpUd->st.wMonth++;
+ if (lpUd->st.wMonth > 12)
+ {
+ lpUd->st.wMonth = 1; /* Roll forward into January of the next year */
+ lpUd->st.wYear++;
+ }
+ }
+ }
+ TRACE("Rolled date: %d/%d/%d %d:%d:%d\n", lpUd->st.wDay, lpUd->st.wMonth,
+ lpUd->st.wYear, lpUd->st.wHour, lpUd->st.wMinute, lpUd->st.wSecond);
+ return S_OK;
+}
+
/**********************************************************************
* DosDateTimeToVariantTime [OLEAUT32.14]
- * Convert dos representation of time to the date and time representation
- * stored in a variant.
+ *
+ * Convert a Dos format date and time into variant VT_DATE format.
+ *
+ * PARAMS
+ * wDosDate [I] Dos format date
+ * wDosTime [I] Dos format time
+ * pDateOut [O] Destination for VT_DATE format
+ *
+ * RETURNS
+ * Success: TRUE. pDateOut contains the converted time.
+ * Failure: FALSE, if wDosDate or wDosTime are invalid (see notes).
+ *
+ * NOTES
+ * - Dos format dates can only hold dates from 1-Jan-1980 to 31-Dec-2099.
+ * - Dos format times are accurate to only 2 second precision.
+ * - The format of a Dos Date is:
+ *| Bits Values Meaning
+ *| ---- ------ -------
+ *| 0-4 1-31 Day of the week. 0 rolls back one day. A value greater than
+ *| the days in the month rolls forward the extra days.
+ *| 5-8 1-12 Month of the year. 0 rolls back to December of the previous
+ *| year. 13-15 are invalid.
+ *| 9-15 0-119 Year based from 1980 (Max 2099). 120-127 are invalid.
+ * - The format of a Dos Time is:
+ *| Bits Values Meaning
+ *| ---- ------ -------
+ *| 0-4 0-29 Seconds/2. 30 and 31 are invalid.
+ *| 5-10 0-59 Minutes. 60-63 are invalid.
+ *| 11-15 0-23 Hours (24 hour clock). 24-32 are invalid.
*/
INT WINAPI DosDateTimeToVariantTime(USHORT wDosDate, USHORT wDosTime,
- DATE *pvtime)
+ double *pDateOut)
{
- struct tm t;
+ UDATE ud;
- TRACE("( 0x%x, 0x%x, %p ), stub\n", wDosDate, wDosTime, pvtime );
+ TRACE("(0x%x(%d/%d/%d),0x%x(%d:%d:%d),%p)\n",
+ wDosDate, DOS_YEAR(wDosDate), DOS_MONTH(wDosDate), DOS_DAY(wDosDate),
+ wDosTime, DOS_HOUR(wDosTime), DOS_MINUTE(wDosTime), DOS_SECOND(wDosTime),
+ pDateOut);
- t.tm_sec = (wDosTime & 0x001f) * 2;
- t.tm_min = (wDosTime & 0x07e0) >> 5;
- t.tm_hour = (wDosTime & 0xf800) >> 11;
+ ud.st.wYear = DOS_YEAR(wDosDate);
+ ud.st.wMonth = DOS_MONTH(wDosDate);
+ if (ud.st.wYear > 2099 || ud.st.wMonth > 12)
+ return FALSE;
+ ud.st.wDay = DOS_DAY(wDosDate);
+ ud.st.wHour = DOS_HOUR(wDosTime);
+ ud.st.wMinute = DOS_MINUTE(wDosTime);
+ ud.st.wSecond = DOS_SECOND(wDosTime);
+ ud.st.wDayOfWeek = ud.st.wMilliseconds = 0;
- t.tm_mday = (wDosDate & 0x001f);
- t.tm_mon = (wDosDate & 0x01e0) >> 5;
- t.tm_year = ((wDosDate & 0xfe00) >> 9) + 1980;
+ return !VarDateFromUdate(&ud, 0, pDateOut);
+}
- return TmToDATE( &t, pvtime );
+/**********************************************************************
+ * VariantTimeToDosDateTime [OLEAUT32.13]
+ *
+ * Convert a variant format date into a Dos format date and time.
+ *
+ * dateIn [I] VT_DATE time format
+ * pwDosDate [O] Destination for Dos format date
+ * pwDosTime [O] Destination for Dos format time
+ *
+ * RETURNS
+ * Success: TRUE. pwDosDate and pwDosTime contains the converted values.
+ * Failure: FALSE, if dateIn cannot be represented in Dos format.
+ *
+ * NOTES
+ * See DosDateTimeToVariantTime() for Dos format details and bugs.
+ */
+INT WINAPI VariantTimeToDosDateTime(double dateIn, USHORT *pwDosDate, USHORT *pwDosTime)
+{
+ UDATE ud;
+
+ TRACE("(%g,%p,%p)\n", dateIn, pwDosDate, pwDosTime);
+
+ if (FAILED(VarUdateFromDate(dateIn, 0, &ud)))
+ return FALSE;
+
+ if (ud.st.wYear < 1980 || ud.st.wYear > 2099)
+ return FALSE;
+
+ *pwDosDate = DOS_DATE(ud.st.wDay, ud.st.wMonth, ud.st.wYear);
+ *pwDosTime = DOS_TIME(ud.st.wHour, ud.st.wMinute, ud.st.wSecond);
+
+ TRACE("Returning 0x%x(%d/%d/%d), 0x%x(%d:%d:%d)\n",
+ *pwDosDate, DOS_YEAR(*pwDosDate), DOS_MONTH(*pwDosDate), DOS_DAY(*pwDosDate),
+ *pwDosTime, DOS_HOUR(*pwDosTime), DOS_MINUTE(*pwDosTime), DOS_SECOND(*pwDosTime));
+ return TRUE;
+}
+
+/***********************************************************************
+ * SystemTimeToVariantTime [OLEAUT32.184]
+ *
+ * Convert a System format date and time into variant VT_DATE format.
+ *
+ * PARAMS
+ * lpSt [I] System format date and time
+ * pDateOut [O] Destination for VT_DATE format date
+ *
+ * RETURNS
+ * Success: TRUE. *pDateOut contains the converted value.
+ * Failure: FALSE, if lpSt cannot be represented in VT_DATE format.
+ */
+INT WINAPI SystemTimeToVariantTime(LPSYSTEMTIME lpSt, double *pDateOut)
+{
+ UDATE ud;
+
+ TRACE("(%p->%d/%d/%d %d:%d:%d,%p)\n", lpSt, lpSt->wDay, lpSt->wMonth,
+ lpSt->wYear, lpSt->wHour, lpSt->wMinute, lpSt->wSecond, pDateOut);
+
+ if (lpSt->wMonth > 12)
+ return FALSE;
+
+ memcpy(&ud.st, lpSt, sizeof(ud.st));
+ return !VarDateFromUdate(&ud, 0, pDateOut);
+}
+
+/***********************************************************************
+ * VariantTimeToSystemTime [OLEAUT32.185]
+ *
+ * Convert a variant VT_DATE into a System format date and time.
+ *
+ * PARAMS
+ * datein [I] Variant VT_DATE format date
+ * lpSt [O] Destination for System format date and time
+ *
+ * RETURNS
+ * Success: TRUE. *lpSt contains the converted value.
+ * Failure: FALSE, if dateIn is too large or small.
+ */
+INT WINAPI VariantTimeToSystemTime(double dateIn, LPSYSTEMTIME lpSt)
+{
+ UDATE ud;
+
+ TRACE("(%g,%p)\n", dateIn, lpSt);
+
+ if (FAILED(VarUdateFromDate(dateIn, 0, &ud)))
+ return FALSE;
+
+ memcpy(lpSt, &ud.st, sizeof(ud.st));
+ return TRUE;
+}
+
+/***********************************************************************
+ * VarDateFromUdate [OLEAUT32.330]
+ *
+ * Convert an unpacked format date and time to a variant VT_DATE.
+ *
+ * PARAMS
+ * pUdateIn [I] Unpacked format date and time to convert
+ * dwFlags [I] Flags controlling the conversion (VAR_ flags from "oleauto.h")
+ * pDateOut [O] Destination for variant VT_DATE.
+ *
+ * RETURNS
+ * Success: S_OK. *pDateOut contains the converted value.
+ * Failure: E_INVALIDARG, if pUdateIn cannot be represented in VT_DATE format.
+ */
+HRESULT WINAPI VarDateFromUdate(UDATE *pUdateIn, ULONG dwFlags, DATE *pDateOut)
+{
+ UDATE ud;
+ double dateVal;
+
+ TRACE("(%p->%d/%d/%d %d:%d:%d:%d %d %d,0x%08lx,%p)\n", pUdateIn,
+ pUdateIn->st.wMonth, pUdateIn->st.wDay, pUdateIn->st.wYear,
+ pUdateIn->st.wHour, pUdateIn->st.wMinute, pUdateIn->st.wSecond,
+ pUdateIn->st.wMilliseconds, pUdateIn->st.wDayOfWeek,
+ pUdateIn->wDayOfYear, dwFlags, pDateOut);
+
+ memcpy(&ud, pUdateIn, sizeof(ud));
+
+ if (dwFlags & VAR_VALIDDATE)
+ WARN("Ignoring VAR_VALIDDATE\n");
+
+ if (FAILED(VARIANT_RollUdate(&ud)))
+ return E_INVALIDARG;
+
+ /* Date */
+ dateVal = VARIANT_DateFromJulian(VARIANT_JulianFromDMY(ud.st.wYear, ud.st.wMonth, ud.st.wDay));
+
+ /* Time */
+ dateVal += ud.st.wHour / 24.0;
+ dateVal += ud.st.wMinute / 1440.0;
+ dateVal += ud.st.wSecond / 86400.0;
+ dateVal += ud.st.wMilliseconds / 86400000.0;
+
+ TRACE("Returning %g\n", dateVal);
+ *pDateOut = dateVal;
+ return S_OK;
+}
+
+/***********************************************************************
+ * VarUdateFromDate [OLEAUT32.331]
+ *
+ * Convert a variant VT_DATE into an unpacked format date and time.
+ *
+ * PARAMS
+ * datein [I] Variant VT_DATE format date
+ * dwFlags [I] Flags controlling the conversion (VAR_ flags from "oleauto.h")
+ * lpUdate [O] Destination for unpacked format date and time
+ *
+ * RETURNS
+ * Success: S_OK. *lpUdate contains the converted value.
+ * Failure: E_INVALIDARG, if dateIn is too large or small.
+ */
+HRESULT WINAPI VarUdateFromDate(DATE dateIn, ULONG dwFlags, UDATE *lpUdate)
+{
+ /* Cumulative totals of days per month */
+ static const USHORT cumulativeDays[] =
+ {
+ 0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
+ };
+ double datePart, timePart;
+ int julianDays;
+
+ TRACE("(%g,0x%08lx,%p)\n", dateIn, dwFlags, lpUdate);
+
+ if (dateIn <= (DATE_MIN - 1.0) || dateIn >= (DATE_MAX + 1.0))
+ return E_INVALIDARG;
+
+ datePart = dateIn < 0.0 ? ceil(dateIn) : floor(dateIn);
+ /* Compensate for int truncation (always downwards) */
+ timePart = dateIn - datePart + 0.00000000001;
+ if (timePart >= 1.0)
+ timePart -= 0.00000000001;
+
+ /* Date */
+ julianDays = VARIANT_JulianFromDate(dateIn);
+ VARIANT_DMYFromJulian(julianDays, &lpUdate->st.wYear, &lpUdate->st.wMonth,
+ &lpUdate->st.wDay);
+
+ datePart = (datePart + 1.5) / 7.0;
+ lpUdate->st.wDayOfWeek = (datePart - floor(datePart)) * 7;
+ if (lpUdate->st.wDayOfWeek == 0)
+ lpUdate->st.wDayOfWeek = 5;
+ else if (lpUdate->st.wDayOfWeek == 1)
+ lpUdate->st.wDayOfWeek = 6;
+ else
+ lpUdate->st.wDayOfWeek -= 2;
+
+ if (lpUdate->st.wMonth > 2 && IsLeapYear(lpUdate->st.wYear))
+ lpUdate->wDayOfYear = 1; /* After February, in a leap year */
+ else
+ lpUdate->wDayOfYear = 0;
+
+ lpUdate->wDayOfYear += cumulativeDays[lpUdate->st.wMonth];
+ lpUdate->wDayOfYear += lpUdate->st.wDay;
+
+ /* Time */
+ timePart *= 24.0;
+ lpUdate->st.wHour = timePart;
+ timePart -= lpUdate->st.wHour;
+ timePart *= 60.0;
+ lpUdate->st.wMinute = timePart;
+ timePart -= lpUdate->st.wMinute;
+ timePart *= 60.0;
+ lpUdate->st.wSecond = timePart;
+ timePart -= lpUdate->st.wSecond;
+ lpUdate->st.wMilliseconds = 0;
+ if (timePart > 0.0005)
+ {
+ /* Round the milliseconds, adjusting the time/date forward if needed */
+ if (lpUdate->st.wSecond < 59)
+ lpUdate->st.wSecond++;
+ else
+ {
+ lpUdate->st.wSecond = 0;
+ if (lpUdate->st.wMinute < 59)
+ lpUdate->st.wMinute++;
+ else
+ {
+ lpUdate->st.wMinute = 0;
+ if (lpUdate->st.wHour < 23)
+ lpUdate->st.wHour++;
+ else
+ {
+ lpUdate->st.wHour = 0;
+ /* Roll over a whole day */
+ if (++lpUdate->st.wDay > 28)
+ VARIANT_RollUdate(lpUdate);
+ }
+ }
+ }
+ }
+ return S_OK;
}
#define GET_NUMBER_TEXT(fld,name) \
@@ -5004,288 +5408,6 @@
}
/**********************************************************************
- * VariantTimeToDosDateTime [OLEAUT32.13]
- * Convert variant representation of time to the date and time representation
- * stored in dos.
- */
-INT WINAPI VariantTimeToDosDateTime(DATE pvtime, USHORT *wDosDate, USHORT *wDosTime)
-{
- struct tm t;
- *wDosTime = 0;
- *wDosDate = 0;
-
- TRACE("( 0x%x, 0x%x, %p ), stub\n", *wDosDate, *wDosTime, &pvtime );
-
- if (DateToTm(pvtime, 0, &t) < 0) return 0;
-
- *wDosTime = *wDosTime | (t.tm_sec / 2);
- *wDosTime = *wDosTime | (t.tm_min << 5);
- *wDosTime = *wDosTime | (t.tm_hour << 11);
-
- *wDosDate = *wDosDate | t.tm_mday ;
- *wDosDate = *wDosDate | t.tm_mon << 5;
- *wDosDate = *wDosDate | ((t.tm_year - 1980) << 9) ;
-
- return 1;
-}
-
-
-/***********************************************************************
- * SystemTimeToVariantTime [OLEAUT32.184]
- */
-HRESULT WINAPI SystemTimeToVariantTime( LPSYSTEMTIME lpSystemTime, double *pvtime )
-{
- struct tm t;
-
- TRACE(" %d/%d/%d %d:%d:%d\n",
- lpSystemTime->wMonth, lpSystemTime->wDay,
- lpSystemTime->wYear, lpSystemTime->wHour,
- lpSystemTime->wMinute, lpSystemTime->wSecond);
-
- if (lpSystemTime->wYear >= 1900)
- {
- t.tm_sec = lpSystemTime->wSecond;
- t.tm_min = lpSystemTime->wMinute;
- t.tm_hour = lpSystemTime->wHour;
-
- t.tm_mday = lpSystemTime->wDay;
- t.tm_mon = lpSystemTime->wMonth - 1; /* tm_mon is 0..11, wMonth is 1..12 */
- t.tm_year = lpSystemTime->wYear;
-
- return TmToDATE( &t, pvtime );
- }
- else
- {
- double tmpDate;
- long firstDayOfNextYear;
- long thisDay;
- long leftInYear;
- long result;
-
- double decimalPart = 0.0;
-
- t.tm_sec = lpSystemTime->wSecond;
- t.tm_min = lpSystemTime->wMinute;
- t.tm_hour = lpSystemTime->wHour;
-
- /* Step year forward the same number of years before 1900 */
- t.tm_year = 1900 + 1899 - lpSystemTime->wYear;
- t.tm_mon = lpSystemTime->wMonth - 1;
- t.tm_mday = lpSystemTime->wDay;
-
- /* Calculate date */
- TmToDATE( &t, pvtime );
-
- thisDay = (double) floor( *pvtime );
- decimalPart = fmod( *pvtime, thisDay );
-
- /* Now, calculate the same time for the first of Jan that year */
- t.tm_mon = 0;
- t.tm_mday = 1;
- t.tm_sec = 0;
- t.tm_min = 0;
- t.tm_hour = 0;
- t.tm_year = t.tm_year+1;
- TmToDATE( &t, &tmpDate );
- firstDayOfNextYear = (long) floor(tmpDate);
-
- /* Finally since we know the size of the year, subtract the two to get
- remaining time in the year */
- leftInYear = firstDayOfNextYear - thisDay;
-
- /* Now we want full years up to the year in question, and remainder of year
- of the year in question */
- if (isleap(lpSystemTime->wYear) ) {
- TRACE("Extra day due to leap year\n");
- result = 2.0 - ((firstDayOfNextYear - 366) + leftInYear - 2.0);
- } else {
- result = 2.0 - ((firstDayOfNextYear - 365) + leftInYear - 2.0);
- }
- *pvtime = (double) result + decimalPart;
- TRACE("<1899 support: returned %f, 1st day %ld, thisday %ld, left %ld\n", *pvtime, firstDayOfNextYear, thisDay, leftInYear);
-
- return 1;
- }
-
- return 0;
-}
-
-/***********************************************************************
- * VariantTimeToSystemTime [OLEAUT32.185]
- */
-HRESULT WINAPI VariantTimeToSystemTime( double vtime, LPSYSTEMTIME lpSystemTime )
-{
- double t = 0, timeofday = 0;
-
- static const BYTE Days_Per_Month[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
- static const BYTE Days_Per_Month_LY[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
-
- /* The Month_Code is used to find the Day of the Week (LY = LeapYear)*/
- static const BYTE Month_Code[] = {0, 1, 4, 4, 0, 2, 5, 0, 3, 6, 1, 4, 6};
- static const BYTE Month_Code_LY[] = {0, 0, 3, 4, 0, 2, 5, 0, 3, 6, 1, 4, 6};
-
- /* The Century_Code is used to find the Day of the Week */
- static const BYTE Century_Code[] = {0, 6, 4, 2};
-
- struct tm r;
-
- TRACE(" Variant = %f SYSTEMTIME ptr %p\n", vtime, lpSystemTime);
-
- if (vtime >= 0)
- {
-
- if (DateToTm(vtime, 0, &r ) <= 0) return 0;
-
- lpSystemTime->wSecond = r.tm_sec;
- lpSystemTime->wMinute = r.tm_min;
- lpSystemTime->wHour = r.tm_hour;
- lpSystemTime->wDay = r.tm_mday;
- lpSystemTime->wMonth = r.tm_mon;
-
- if (lpSystemTime->wMonth == 12)
- lpSystemTime->wMonth = 1;
- else
- lpSystemTime->wMonth++;
-
- lpSystemTime->wYear = r.tm_year;
- }
- else
- {
- vtime = -1*vtime;
-
- if (DateToTm(vtime, 0, &r ) <= 0) return 0;
-
- lpSystemTime->wSecond = r.tm_sec;
- lpSystemTime->wMinute = r.tm_min;
- lpSystemTime->wHour = r.tm_hour;
-
- lpSystemTime->wMonth = 13 - r.tm_mon;
-
- if (lpSystemTime->wMonth == 1)
- lpSystemTime->wMonth = 12;
- else
- lpSystemTime->wMonth--;
-
- lpSystemTime->wYear = 1899 - (r.tm_year - 1900);
-
- if (!isleap(lpSystemTime->wYear) )
- lpSystemTime->wDay = Days_Per_Month[13 - lpSystemTime->wMonth] - r.tm_mday;
- else
- lpSystemTime->wDay = Days_Per_Month_LY[13 - lpSystemTime->wMonth] - r.tm_mday;
-
-
- }
-
- if (!isleap(lpSystemTime->wYear))
- {
- /*
- (Century_Code+Month_Code+Year_Code+Day) % 7
-
- The century code repeats every 400 years , so the array
- works out like this,
-
- Century_Code[0] is for 16th/20th Centry
- Century_Code[1] is for 17th/21th Centry
- Century_Code[2] is for 18th/22th Centry
- Century_Code[3] is for 19th/23th Centry
-
- The year code is found with the formula (year + (year / 4))
- the "year" must be between 0 and 99 .
-
- The Month Code (Month_Code[1]) starts with January and
- ends with December.
- */
-
- lpSystemTime->wDayOfWeek = (
- Century_Code[(( (lpSystemTime->wYear+100) - lpSystemTime->wYear%100) /100) %4]+
- ((lpSystemTime->wYear%100)+(lpSystemTime->wYear%100)/4)+
- Month_Code[lpSystemTime->wMonth]+
- lpSystemTime->wDay) % 7;
-
- if (lpSystemTime->wDayOfWeek == 0) lpSystemTime->wDayOfWeek = 7;
- else lpSystemTime->wDayOfWeek -= 1;
- }
- else
- {
- lpSystemTime->wDayOfWeek = (
- Century_Code[(((lpSystemTime->wYear+100) - lpSystemTime->wYear%100)/100)%4]+
- ((lpSystemTime->wYear%100)+(lpSystemTime->wYear%100)/4)+
- Month_Code_LY[lpSystemTime->wMonth]+
- lpSystemTime->wDay) % 7;
-
- if (lpSystemTime->wDayOfWeek == 0) lpSystemTime->wDayOfWeek = 7;
- else lpSystemTime->wDayOfWeek -= 1;
- }
-
- t = floor(vtime);
- timeofday = vtime - t;
-
- lpSystemTime->wMilliseconds = (timeofday
- - lpSystemTime->wHour*(1/24)
- - lpSystemTime->wMinute*(1/1440)
- - lpSystemTime->wSecond*(1/86400) )*(1/5184000);
-
- return 1;
-}
-
-/***********************************************************************
- * VarUdateFromDate [OLEAUT32.331]
- */
-HRESULT WINAPI VarUdateFromDate( DATE datein, ULONG dwFlags, UDATE *pudateout)
-{
- HRESULT i = 0;
- static const BYTE Days_Per_Month[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
- static const BYTE Days_Per_Month_LY[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
-
- TRACE("DATE = %f\n", (double)datein);
- i = VariantTimeToSystemTime(datein, &(pudateout->st) );
-
- if (i)
- {
- pudateout->wDayOfYear = 0;
-
- if (isleap(pudateout->st.wYear))
- {
- for (i =1; i<pudateout->st.wMonth; i++)
- pudateout->wDayOfYear += Days_Per_Month[i];
- }
- else
- {
- for (i =1; i<pudateout->st.wMonth; i++)
- pudateout->wDayOfYear += Days_Per_Month_LY[i];
- }
-
- pudateout->wDayOfYear += pudateout->st.wDay;
- dwFlags = 0; /*VAR_VALIDDATE*/
- }
- else dwFlags = 0;
-
- return i;
-}
-
-/***********************************************************************
- * VarDateFromUdate [OLEAUT32.330]
- */
-HRESULT WINAPI VarDateFromUdate(UDATE *pudateout,
- ULONG dwFlags, DATE *datein)
-{
- HRESULT i;
- double t = 0;
- TRACE(" %d/%d/%d %d:%d:%d\n",
- pudateout->st.wMonth, pudateout->st.wDay,
- pudateout->st.wYear, pudateout->st.wHour,
- pudateout->st.wMinute, pudateout->st.wSecond);
-
-
- i = SystemTimeToVariantTime(&(pudateout->st), &t);
- *datein = t;
-
- if (i) return S_OK;
- else return E_INVALIDARG;
-}
-
-
-/**********************************************************************
* VarBstrCmp [OLEAUT32.314]
*
* flags can be: