Index: trunk/src/oleaut32/dispatch.c
===================================================================
--- trunk/src/oleaut32/dispatch.c	(revision 6942)
+++ trunk/src/oleaut32/dispatch.c	(revision 6944)
@@ -8,9 +8,6 @@
  * TODO: Type coercion is implemented in variant.c but not called yet.
  */
-#ifdef __WIN32OS2__
-#define HAVE_FLOAT_H
-#define WINE_LARGE_INTEGER
-#include "oleaut32.h"
-#endif
+
+#include "config.h"
 
 #include <stdlib.h>
@@ -18,10 +15,14 @@
 #include <stdio.h>
 #include <ctype.h>
+
+#include "windef.h"
+#include "ole.h"
+#include "oleauto.h"
 #include "winerror.h"
 #include "winreg.h"         /* for HKEY_LOCAL_MACHINE */
 #include "winnls.h"         /* for PRIMARYLANGID */
-#include "ole.h"
-#include "heap.h"
+
 #include "wine/obj_oleaut.h"
+
 #include "debugtools.h"
 
@@ -31,5 +32,5 @@
 
 /******************************************************************************
- *         DispInvoke    (OLEAUT32.30)
+ *		DispInvoke (OLEAUT32.30)
  *
  *
@@ -43,14 +44,13 @@
  * 		S_OK on success.
  */
-HRESULT WINAPI
-DispInvoke(VOID*            _this,          /* object instance */
-           ITypeInfo*       ptinfo,         /* object's type info */
-           DISPID           dispidMember,   /* member id */
-           USHORT           wFlags,         /* kind of method call */
-           DISPPARAMS*      pparams,        /* array of arguments */
-           VARIANT*         pvarResult,     /* result of method call */
-           EXCEPINFO*       pexcepinfo,     /* information about exception */
-           UINT*            puArgErr        /* index of bad argument(if any) */
-          )
+HRESULT WINAPI DispInvoke(
+	VOID       *_this,        /* [in] object instance */
+	ITypeInfo  *ptinfo,       /* [in] object's type info */
+	DISPID      dispidMember, /* [in] member id */
+	USHORT      wFlags,       /* [in] kind of method call */
+	DISPPARAMS *pparams,      /* [in] array of arguments */
+	VARIANT    *pvarResult,   /* [out] result of method call */
+	EXCEPINFO  *pexcepinfo,   /* [out] information about exception */
+	UINT       *puArgErr)     /* [out] index of bad argument(if any) */
 {
     HRESULT hr = E_FAIL;
@@ -74,5 +74,5 @@
 
 /******************************************************************************
- *         DispGetIDsOfNames (OLEAUT32.29)
+ *		DispGetIDsOfNames (OLEAUT32.29)
  *
  * Convert a set of names to dispids, based on information 
@@ -86,9 +86,9 @@
  * 		S_OK on success.
  */
-HRESULT WINAPI
-DispGetIDsOfNames(ITypeInfo* ptinfo,
-                  OLECHAR**  rgszNames,
-                  UINT       cNames,
-                  DISPID*    rgdispid)
+HRESULT WINAPI DispGetIDsOfNames(
+	ITypeInfo  *ptinfo,    /* [in] */
+	OLECHAR   **rgszNames, /* [in] */
+	UINT        cNames,    /* [in] */
+	DISPID     *rgdispid)  /* [out] */
 {
     HRESULT hr = E_FAIL;
@@ -103,5 +103,5 @@
 
 /******************************************************************************
- *         DispGetParam    (OLEAUT32.30)
+ *		DispGetParam (OLEAUT32.28)
  *
  * Retrive a parameter from a DISPPARAMS structures and coerce it to
@@ -115,14 +115,32 @@
  * 		S_OK on success.
  */
-HRESULT WINAPI DispGetParam(DISPPARAMS* pdispparams, UINT position,
-            VARTYPE vtTarg, VARIANT* pvarResult, UINT* puArgErr)
+HRESULT WINAPI DispGetParam(
+	DISPPARAMS *pdispparams, /* [in] */
+	UINT        position,    /* [in] */
+	VARTYPE     vtTarg,      /* [in] */
+	VARIANT    *pvarResult,  /* [out] */
+	UINT       *puArgErr)    /* [out] */
 {
-    HRESULT hr = E_FAIL;
+    /* position is counted backwards */
+    UINT pos;
+    HRESULT hr;
 
-    /**
-     * TODO : Call VariantChangeTypeEx with LCID 0 (system)
-     */
+    TRACE("position=%d, cArgs=%d, cNamedArgs=%d\n",
+          position, pdispparams->cArgs, pdispparams->cNamedArgs);
+    if (position < pdispparams->cArgs) {
+      /* positional arg? */
+      pos = pdispparams->cArgs - position - 1;
+    } else {
+      /* FIXME: is this how to handle named args? */
+      for (pos=0; pos<pdispparams->cNamedArgs; pos++)
+        if (pdispparams->rgdispidNamedArgs[pos] == position) break;
 
-    FIXME("Coercion of arguments not implemented\n");
-    return (hr);
+      if (pos==pdispparams->cNamedArgs)
+        return DISP_E_PARAMNOTFOUND;
+    }
+    hr = VariantChangeType(pvarResult,
+                           &pdispparams->rgvarg[pos],
+                           0, vtTarg);
+    if (hr == DISP_E_TYPEMISMATCH) *puArgErr = pos;
+    return hr;
 }
Index: trunk/src/oleaut32/oleaut.c
===================================================================
--- trunk/src/oleaut32/oleaut.c	(revision 6942)
+++ trunk/src/oleaut32/oleaut.c	(revision 6944)
@@ -3,4 +3,10 @@
  *
  */
+#ifdef __WIN32OS2__
+#define HAVE_FLOAT_H
+#define WINE_LARGE_INTEGER
+#include "oleaut32.h"
+#endif
+
 #include <string.h>
 
@@ -12,5 +18,7 @@
 
 #include "ole2.h"
-#include "heap.h"
+#include "olectl.h"
+#include "wine/obj_oleaut.h"
+#include "wine/obj_olefont.h"
 #include "debugtools.h"
 
@@ -139,5 +147,4 @@
 }
 
-#ifndef __WIN32OS2__
 /***********************************************************************
  *		DllRegisterServer
@@ -155,3 +162,30 @@
     return S_OK;
 }
-#endif //__WIN32OS2__
+
+
+extern void _get_STDFONT_CF(LPVOID);
+
+/***********************************************************************
+ *		DllGetClassObject (OLEAUT32.1)
+ */
+HRESULT WINAPI OLEAUT32_DllGetClassObject(REFCLSID rclsid, REFIID iid,LPVOID *ppv)
+{
+    *ppv = NULL;
+    if (IsEqualGUID(rclsid,&CLSID_StdFont)) {
+	if (IsEqualGUID(iid,&IID_IClassFactory)) {
+	    _get_STDFONT_CF(ppv);
+	    IClassFactory_AddRef((IClassFactory*)*ppv);
+	    return S_OK;
+	}
+    }
+    FIXME("\n\tCLSID:\t%s,\n\tIID:\t%s\n",debugstr_guid(rclsid),debugstr_guid(iid));
+    return CLASS_E_CLASSNOTAVAILABLE;
+}
+
+/***********************************************************************
+ *		DllCanUnloadNow (OLEAUT32.410)
+ */
+HRESULT WINAPI OLEAUT32_DllCanUnloadNow() {
+    FIXME("(), stub!\n");
+    return S_FALSE;
+}
Index: trunk/src/oleaut32/oleaut32.def
===================================================================
--- trunk/src/oleaut32/oleaut32.def	(revision 6942)
+++ trunk/src/oleaut32/oleaut32.def	(revision 6944)
@@ -1,3 +1,3 @@
-;/* $Id: oleaut32.def,v 1.7 2001-08-23 18:11:20 sandervl Exp $ */
+;/* $Id: oleaut32.def,v 1.8 2001-10-03 19:21:59 sandervl Exp $ */
 LIBRARY OLAUTOS2 INITINSTANCE
 DESCRIPTION 'Odin32 System DLL - OleAut32'
@@ -5,5 +5,5 @@
 
 EXPORTS
-DllGetClassObject = _DllGetClassObject@12  @1
+DllGetClassObject = _OLEAUT32_DllGetClassObject@12  @1
 SysAllocString = _SysAllocString@4  @2
 SysReAllocString = _SysReAllocString@8  @3
@@ -254,6 +254,6 @@
 LPSAFEARRAY_Marshal = _LPSAFEARRAY_Marshal@0  @296
 LPSAFEARRAY_Unmarshal = _LPSAFEARRAY_Unmarshal@0  @297
-DllRegisterServer = _DllRegisterServer@0  @320
-DllUnregisterServer = _DllUnregisterServer@0  @321
+DllRegisterServer = _OLEAUT32_DllRegisterServer@0  @320
+DllUnregisterServer = _OLEAUT32_DllUnregisterServer@0  @321
 VarDateFromUdate = _VarDateFromUdate@12  @330
 VarUdateFromDate = _VarUdateFromDate@16  @331
@@ -279,5 +279,5 @@
 UserMSG_free_inst = _UserMSG_free_inst@0  @398
 UserMSG_free_local = _UserMSG_free_local@0  @399
-DllCanUnloadNow = _DllCanUnloadNow@0  @410
+DllCanUnloadNow = _OLEAUT32_DllCanUnloadNow@0  @410
 SafeArrayCreateVector = _SafeArrayCreateVector@12  @411
 SafeArrayCopyData = _SafeArrayCopyData@8  @412
Index: trunk/src/oleaut32/oleaut32.h
===================================================================
--- trunk/src/oleaut32/oleaut32.h	(revision 6942)
+++ trunk/src/oleaut32/oleaut32.h	(revision 6944)
@@ -1,3 +1,3 @@
-/* $Id: oleaut32.h,v 1.10 2001-04-04 09:02:15 sandervl Exp $ */
+/* $Id: oleaut32.h,v 1.11 2001-10-03 19:21:59 sandervl Exp $ */
 /*
  * Win32 OLE stubs for OS/2
@@ -59,3 +59,4 @@
 void OpenPrivateLogFileTypelib();
 
+#define snprintf wsnprintfA
 #endif
Index: trunk/src/oleaut32/safearray.c
===================================================================
--- trunk/src/oleaut32/safearray.c	(revision 6942)
+++ trunk/src/oleaut32/safearray.c	(revision 6944)
@@ -8,9 +8,4 @@
  */
 
-#ifdef __WIN32OS2__
-#define HAVE_FLOAT_H
-#define WINE_LARGE_INTEGER
-#include "oleaut32.h"
-#endif
 #include <stdio.h>
 #include <string.h>
@@ -24,4 +19,6 @@
 DEFAULT_DEBUG_CHANNEL(ole);
 
+#define SYSDUPSTRING(str) SysAllocStringLen((str), SysStringLen(str))
+
 /* Localy used methods */
 static INT  
@@ -59,22 +56,22 @@
 {
   /* this is taken from wtypes.h.  Only [S]es are supported by the SafeArray */
-VARTYPE_NOT_SUPPORTED,	/* VT_EMPTY    [V]   [P]    nothing			*/
-VARTYPE_NOT_SUPPORTED,	/* VT_NULL     [V]   [P]    SQL style Nul	*/
-2,	                    /* VT_I2       [V][T][P][S] 2 byte signed int */
-4, 	                    /* VT_I4       [V][T][P][S] 4 byte signed int */
-4, 	                    /* VT_R4       [V][T][P][S] 4 byte real	*/
-8,	                    /* VT_R8       [V][T][P][S] 8 byte real	*/
+VARTYPE_NOT_SUPPORTED,  /* VT_EMPTY    [V]   [P]    nothing			*/
+VARTYPE_NOT_SUPPORTED,  /* VT_NULL     [V]   [P]    SQL style Nul	*/
+2,                      /* VT_I2       [V][T][P][S] 2 byte signed int */
+4,                      /* VT_I4       [V][T][P][S] 4 byte signed int */
+4,                      /* VT_R4       [V][T][P][S] 4 byte real	*/
+8,                      /* VT_R8       [V][T][P][S] 8 byte real	*/
 8,                      /* VT_CY       [V][T][P][S] currency */
-8,	                    /* VT_DATE     [V][T][P][S] date */
-4,	                    /* VT_BSTR     [V][T][P][S] OLE Automation string*/
-4,	                    /* VT_DISPATCH [V][T][P][S] IDispatch *	*/
+8,                      /* VT_DATE     [V][T][P][S] date */
+sizeof(BSTR),           /* VT_BSTR     [V][T][P][S] OLE Automation string*/
+sizeof(LPDISPATCH),     /* VT_DISPATCH [V][T][P][S] IDispatch *	*/
 4,                      /* VT_ERROR    [V][T]   [S] SCODE	*/
-4,	                    /* VT_BOOL     [V][T][P][S] True=-1, False=0*/
-24,                     /* VT_VARIANT  [V][T][P][S] VARIANT *	*/
-4,	                    /* VT_UNKNOWN  [V][T]   [S] IUnknown * */
-16,	                    /* VT_DECIMAL  [V][T]   [S] 16 byte fixed point	*/
+4,                      /* VT_BOOL     [V][T][P][S] True=-1, False=0*/
+sizeof(VARIANT),        /* VT_VARIANT  [V][T][P][S] VARIANT *	*/
+sizeof(LPUNKNOWN),      /* VT_UNKNOWN  [V][T]   [S] IUnknown * */
+sizeof(DECIMAL),        /* VT_DECIMAL  [V][T]   [S] 16 byte fixed point	*/
 VARTYPE_NOT_SUPPORTED,                         /* no VARTYPE here..... */
 VARTYPE_NOT_SUPPORTED,	/* VT_I1          [T]       signed char	*/
-1,	                    /* VT_UI1      [V][T][P][S] unsigned char			*/
+1,                      /* VT_UI1      [V][T][P][S] unsigned char			*/
 VARTYPE_NOT_SUPPORTED,	/* VT_UI2         [T][P]    unsigned short	*/
 VARTYPE_NOT_SUPPORTED,	/* VT_UI4         [T][P]    unsigned short	*/
@@ -109,5 +106,5 @@
 
 /*************************************************************************
- *		SafeArrayAllocDescriptor
+ *		SafeArrayAllocDescriptor (OLEAUT32.36)
  * Allocate the appropriate amount of memory for the SafeArray descriptor
  */
@@ -134,5 +131,5 @@
 
 /*************************************************************************
- *		SafeArrayAllocData
+ *		SafeArrayAllocData (OLEAUT32.37)
  * Allocate the appropriate amount of data for the SafeArray data
  */
@@ -141,6 +138,4 @@
 {
   ULONG  ulWholeArraySize;   /* to store the size of the whole thing */
-
-  dprintf(("SafeArrayAllocData %x", psa));
 
   if(! validArg(psa)) 
@@ -161,5 +156,5 @@
 
 /*************************************************************************
- *		SafeArrayCreate
+ *		SafeArrayCreate (OLEAUT32.15)
  * Create a SafeArray object by encapsulating AllocDescriptor and AllocData 
  */
@@ -172,6 +167,4 @@
   HRESULT   hRes;
   USHORT    cDim;
-
-  dprintf(("SafeArrayCreate %x %d %x", vt, cDims, rgsabound));
 
   /* Validate supported VARTYPE */
@@ -208,5 +201,5 @@
 
 /*************************************************************************
- *		SafeArrayDestroyDescriptor
+ *		SafeArrayDestroyDescriptor (OLEAUT32.38)
  * Frees the memory associated with the descriptor.
  */
@@ -214,6 +207,4 @@
   SAFEARRAY *psa)
 {
-  dprintf(("SafeArrayDestroyDescriptor %x", psa));
-
   /* Check for lockness before to free... */
   if(psa->cLocks > 0) 
@@ -229,5 +220,5 @@
 
 /*************************************************************************
- *		SafeArrayLock
+ *		SafeArrayLock (OLEAUT32.21)
  * Increment the lock counter
  *
@@ -239,6 +230,4 @@
   SAFEARRAY *psa)
 {
-  dprintf(("SafeArrayLock %x", psa));
-
   if(! validArg(psa))     
     return E_INVALIDARG;
@@ -250,5 +239,5 @@
 
 /*************************************************************************
- *		SafeArrayUnlock
+ *		SafeArrayUnlock (OLEAUT32.22)
  * Decrement the lock counter
  */
@@ -256,6 +245,4 @@
   SAFEARRAY *psa)
 {
-  dprintf(("SafeArrayUnlock %x", psa));
-
   if(! validArg(psa)) 
     return E_INVALIDARG;
@@ -269,5 +256,5 @@
 
 /*************************************************************************
- *		SafeArrayPutElement
+ *		SafeArrayPutElement (OLEAUT32.26)
  * Set the data at the given coordinate
  */
@@ -280,7 +267,4 @@
                                          the desired one... */
   PVOID elementStorageAddress = NULL; /* Adress to store the data */
-  BSTR  pbstrReAllocStr     = NULL; /* BSTR reallocated */
-
-  dprintf(("SafeArrayPutElement %x %x %x", psa, rgIndices, pv));
 
   /* Validate the index given */
@@ -300,5 +284,5 @@
     if(isPointer(psa->fFeatures)) { /* increment ref count for this pointer */
 
-      *((VOID**)elementStorageAddress) = *(VOID**)pv; 
+      *((PVOID*)elementStorageAddress) = *(PVOID*)pv; 
       IUnknown_AddRef( *(IUnknown**)pv);
 
@@ -306,12 +290,20 @@
 
       if(psa->fFeatures == FADF_BSTR) { /* Create a new object */
-
-        if((pbstrReAllocStr = SysAllocString( (OLECHAR*)pv )) == NULL) {
+        BSTR pbstrReAllocStr = NULL;
+        if(pv &&
+           ((pbstrReAllocStr = SYSDUPSTRING( (OLECHAR*)pv )) == NULL)) {
           SafeArrayUnlock(psa);  
           return E_OUTOFMEMORY;
         } else 
           *((BSTR*)elementStorageAddress) = pbstrReAllocStr;
-
-      } else /* dupplicate the memory */
+      }
+      else if(psa->fFeatures == FADF_VARIANT) {
+        HRESULT hr = VariantCopy(elementStorageAddress, pv);
+        if (FAILED(hr)) {
+          SafeArrayUnlock(psa);
+          return hr;
+        }
+      }
+      else /* duplicate the memory */
         memcpy(elementStorageAddress, pv, SafeArrayGetElemsize(psa) );
     }
@@ -328,5 +320,5 @@
 
 /*************************************************************************
- *		SafeArrayGetElement
+ *		SafeArrayGetElement (OLEAUT32.25)
  * Return the data element corresponding the the given coordinate
  */
@@ -339,7 +331,4 @@
                                          the desired one... */
   PVOID elementStorageAddress = NULL; /* Adress to store the data */
-  BSTR  pbstrReturnedStr    = NULL; /* BSTR reallocated */
-
-  dprintf(("SafeArrayGetElement %x %x %x", psa, rgIndices, pv));
 
   if(! validArg(psa)) 
@@ -358,15 +347,24 @@
   
     if( psa->fFeatures == FADF_BSTR) {           /* reallocate the obj */
-      if( (pbstrReturnedStr = 
-          SysAllocString( *(OLECHAR**)elementStorageAddress )) == NULL) {
+      BSTR pbstrStoredStr = *(OLECHAR**)elementStorageAddress;
+      BSTR pbstrReturnedStr = NULL;
+      if( pbstrStoredStr &&
+          ((pbstrReturnedStr = SYSDUPSTRING( pbstrStoredStr )) == NULL) ) {
         SafeArrayUnlock(psa);
         return E_OUTOFMEMORY;
       } else 
         *((BSTR*)pv) = pbstrReturnedStr; 
-        
-    } else if( isPointer(psa->fFeatures) )       /* simply copy the pointer */
-       pv = *((PVOID*)elementStorageAddress); 
+    }
+    else if( psa->fFeatures == FADF_VARIANT) {
+      HRESULT hr = VariantCopy(pv, elementStorageAddress);
+      if (FAILED(hr)) {
+        SafeArrayUnlock(psa);
+        return hr;
+      }
+    }
+    else if( isPointer(psa->fFeatures) )         /* simply copy the pointer */
+      *(PVOID*)pv = *((PVOID*)elementStorageAddress); 
     else                                         /* copy the bytes */
-      memcpy(pv, elementStorageAddress, SafeArrayGetElemsize(psa) );
+      memcpy(pv, elementStorageAddress, psa->cbElements );
 
   } else {
@@ -379,5 +377,5 @@
 
 /*************************************************************************
- *		SafeArrayGetUBound
+ *		SafeArrayGetUBound (OLEAUT32.19)
  * return the UP bound for a given array dimension
  */
@@ -387,7 +385,4 @@
   LONG      *plUbound)
 {
-
-  dprintf(("SafeArrayGetUBound %x %x %x", psa, nDim, plUbound));
-
   if(! validArg(psa))   
     return E_INVALIDARG;
@@ -396,4 +391,7 @@
     return DISP_E_BADINDEX;
 
+  if(0 == nDim)
+    return DISP_E_BADINDEX;
+
   *plUbound = psa->rgsabound[nDim-1].lLbound + 
               psa->rgsabound[nDim-1].cElements - 1;
@@ -403,5 +401,5 @@
 
 /*************************************************************************
- *		SafeArrayGetLBound
+ *		SafeArrayGetLBound (OLEAUT32.20)
  * Return the LO bound for a given array dimension 
  */
@@ -417,4 +415,7 @@
     return DISP_E_BADINDEX;
 
+  if(0 == nDim)
+    return DISP_E_BADINDEX;
+  
   *plLbound = psa->rgsabound[nDim-1].lLbound;
   return S_OK;
@@ -422,5 +423,5 @@
 
 /*************************************************************************
- *		SafeArrayGetDim
+ *		SafeArrayGetDim (OLEAUT32.17)
  * returns the number of dimension in the array
  */
@@ -439,5 +440,5 @@
 
 /*************************************************************************
- *		SafeArrayGetElemsize
+ *		SafeArrayGetElemsize (OLEAUT32.18)
  * Return the size of the element in the array
  */
@@ -456,5 +457,5 @@
 
 /*************************************************************************
- *		SafeArrayAccessData
+ *		SafeArrayAccessData (OLEAUT32.23)
  * increment the access count and return the data 
  */
@@ -484,5 +485,5 @@
 
 /*************************************************************************
- *		SafeArrayUnaccessData
+ *		SafeArrayUnaccessData (OLEAUT32.24)
  * Decrement the access count
  */
@@ -497,5 +498,5 @@
 
 /************************************************************************ 
- *		SafeArrayPtrOfIndex
+ *		SafeArrayPtrOfIndex (OLEAUT32.148)
  * Return a pointer to the element at rgIndices
  */
@@ -523,5 +524,5 @@
 
 /************************************************************************ 
- *		SafeArrayDestroyData
+ *		SafeArrayDestroyData (OLEAUT32.39)
  * Frees the memory data bloc
  */
@@ -532,6 +533,4 @@
   ULONG    ulWholeArraySize; /* count spot in array  */
   ULONG    ulDataIter;       /* to iterate the data space */
-  IUnknown *punk;
-  BSTR   bstr;
 
   if(! validArg(psa)) 
@@ -544,4 +543,5 @@
 
   if(isPointer(psa->fFeatures)) {           /* release the pointers */
+    IUnknown *punk;
 
     for(ulDataIter=0; ulDataIter < ulWholeArraySize; ulDataIter++) {
@@ -552,5 +552,7 @@
     }
 
-  } else if(psa->fFeatures & FADF_BSTR) {  /* deallocate the obj */
+  }
+  else if(psa->fFeatures & FADF_BSTR) {  /* deallocate the obj */
+    BSTR bstr;
 
     for(ulDataIter=0; ulDataIter < ulWholeArraySize; ulDataIter++) {
@@ -559,4 +561,10 @@
       if( bstr != NULL) 
         SysFreeString( bstr );
+    }
+  }
+  else if(psa->fFeatures & FADF_VARIANT) {  /* deallocate the obj */
+
+    for(ulDataIter=0; ulDataIter < ulWholeArraySize; ulDataIter++) {
+      VariantClear((VARIANT*)((char *) psa->pvData+(ulDataIter*(psa->cbElements))));
     }
   }
@@ -578,5 +586,5 @@
 
 /************************************************************************ 
- *		SafeArrayCopyData
+ *		SafeArrayCopyData (OLEAUT32.412)
  * Copy the psaSource's data block into psaTarget if dimension and size
  * permits it.
@@ -616,5 +624,6 @@
     }
 
-  } else if( (*psaTarget)->fFeatures & FADF_BSTR) {  /* the target contain BSTR
+  }
+  else if( (*psaTarget)->fFeatures & FADF_BSTR) {    /* the target contain BSTR
                                                         that must be freed */ 
     for(lDelta=0;lDelta < ulWholeArraySize; lDelta++) {
@@ -626,4 +635,10 @@
     }
   }
+  else if( (*psaTarget)->fFeatures & FADF_VARIANT) {
+
+    for(lDelta=0;lDelta < ulWholeArraySize; lDelta++) {
+      VariantClear((VARIANT*)((char *) (*psaTarget)->pvData + (lDelta * (*psaTarget)->cbElements)));
+    }
+  }
 
   return duplicateData(psaSource, psaTarget);
@@ -631,5 +646,5 @@
 
 /************************************************************************ 
- *		SafeArrayDestroy
+ *		SafeArrayDestroy (OLEAUT32.16)
  * Deallocates all memory reserved for the SafeArray
  */
@@ -653,5 +668,5 @@
 
 /************************************************************************ 
- *		SafeArrayCopy
+ *		SafeArrayCopy (OLEAUT32.27)
  * Make a dupplicate of a SafeArray
  */
@@ -706,5 +721,5 @@
 
 /************************************************************************ 
- *		SafeArrayCreateVector
+ *		SafeArrayCreateVector (OLEAUT32.411)
  * Creates a one dimension safearray where the data is next to the 
  * SAFEARRAY structure.
@@ -743,5 +758,5 @@
 
 /************************************************************************ 
- *		SafeArrayRedim
+ *		SafeArrayRedim (OLEAUT32.40)
  * Changes the caracteristics of the last dimension of the SafeArray
  */
@@ -808,4 +823,5 @@
   /* Check whether the size of the chunk makes sense... That's the only thing
      I can think of now... */
+
   psaSize = HeapSize(GetProcessHeap(), 0, psa);
   if (psaSize == -1)
@@ -838,5 +854,5 @@
   if(lDelta < 0) {                    /* array needs to be shorthen  */
     if( isPointer(psa->fFeatures))    /* ptr that need to be released */
-	    for(;lDelta < 0; lDelta++) {
+      for(;lDelta < 0; lDelta++) {
 	      punk = *(IUnknown**)
           ((char *) psa->pvData+((ulWholeArraySize+lDelta)*psa->cbElements));
@@ -847,5 +863,5 @@
 
     else if(psa->fFeatures & FADF_BSTR)  /* BSTR that need to be freed */
-	    for(;lDelta < 0; lDelta++) {
+      for(;lDelta < 0; lDelta++) {
         bstr = *(BSTR*)
           ((char *) psa->pvData+((ulWholeArraySize+lDelta)*psa->cbElements));
@@ -853,4 +869,8 @@
         if( bstr != NULL )
           SysFreeString( bstr );
+      }
+    else if(psa->fFeatures & FADF_VARIANT)
+      for(;lDelta < 0; lDelta++) {
+        VariantClear((VARIANT*)((char *) psa->pvData+((ulWholeArraySize+lDelta)*psa->cbElements)));
       }
   }
@@ -894,7 +914,8 @@
 {
   switch(vt) {
+    case VT_BSTR:      return FADF_BSTR;
     case VT_UNKNOWN:   return FADF_UNKNOWN;
     case VT_DISPATCH:  return FADF_DISPATCH;
-    case VT_BSTR:      return FADF_BSTR;
+    case VT_VARIANT:   return FADF_VARIANT;
   }
   return 0;
@@ -973,7 +994,7 @@
 
   for(; iter<psa->cDims; iter++) {
-    if((hRes = SafeArrayGetLBound(psa, iter, &lLBound)) != S_OK)
+    if((hRes = SafeArrayGetLBound(psa, (iter+1), &lLBound)) != S_OK)
       return FALSE;
-    if((hRes = SafeArrayGetUBound(psa, iter, &lUBound)) != S_OK)
+    if((hRes = SafeArrayGetUBound(psa, (iter+1), &lUBound)) != S_OK)
       return FALSE;
  
@@ -1014,6 +1035,4 @@
   ULONG    ulWholeArraySize; /* size of the thing */
   LONG     lDelta;
-  IUnknown *punk;
-  BSTR   pbstrReAllocStr = NULL; /* BSTR reallocated */
 
   ulWholeArraySize = getArraySize(psa); /* Number of item in SA */
@@ -1023,4 +1042,5 @@
   if( isPointer(psa->fFeatures) ) {  /* If datatype is object increment 
                                         object's reference count */
+    IUnknown *punk;
 
     for(lDelta=0; lDelta < ulWholeArraySize; lDelta++) {
@@ -1035,9 +1055,11 @@
       ulWholeArraySize*psa->cbElements);
 
-  } else if( psa->fFeatures & FADF_BSTR ) { /* if datatype is BSTR allocate 
-                                               the BSTR in the new array */
+  }
+  else if( psa->fFeatures & FADF_BSTR ) { /* if datatype is BSTR allocate 
+                                             the BSTR in the new array */
+    BSTR   pbstrReAllocStr = NULL;
 
     for(lDelta=0; lDelta < ulWholeArraySize; lDelta++) {
-      if(( pbstrReAllocStr = SysAllocString(
+      if(( pbstrReAllocStr = SYSDUPSTRING(
             *(BSTR*)((char *) psa->pvData+(lDelta * psa->cbElements)))) == NULL) {
 
@@ -1050,5 +1072,14 @@
     }
 
-  } else { /* Simply copy the source array data into target array */
+  }
+  else if( psa->fFeatures & FADF_VARIANT ) {
+
+    for(lDelta=0; lDelta < ulWholeArraySize; lDelta++) {
+      VariantCopy((VARIANT*)((char *) (*ppsaOut)->pvData+(lDelta * psa->cbElements)),
+                  (VARIANT*)((char *) psa->pvData+(lDelta * psa->cbElements)));
+    }
+
+  }
+  else { /* Simply copy the source array data into target array */
 
     memcpy((*ppsaOut)->pvData, psa->pvData, 
@@ -1063,5 +1094,5 @@
 
 /************************************************************************ 
- *		SafeArrayGetVarType
+ *		SafeArrayGetVarType (OLEAUT32.77)
  * Returns the VARTYPE stored in the given safearray
  */
@@ -1078,5 +1109,5 @@
   {
     /* VT tag @ negative offset 4 in the array descriptor */
-    FIXME("Returning VT_BSTR instead of VT_...");
+    FIXME("Returning VT_BSTR instead of VT_...\n");
     vt = VT_BSTR;
   }
@@ -1085,11 +1116,19 @@
     vt = VT_RECORD;
   }
+  else if (psa->fFeatures & FADF_BSTR)
+  {
+    vt = VT_BSTR;
+  }
+  else if (psa->fFeatures & FADF_UNKNOWN)
+  {
+    vt = VT_UNKNOWN;
+  }
   else if (psa->fFeatures & FADF_DISPATCH)
   {
     vt = VT_DISPATCH;
   }
-  else if (psa->fFeatures & FADF_UNKNOWN)
+  else if (psa->fFeatures & FADF_VARIANT)
   {
-    vt = VT_UNKNOWN;
+    vt = VT_VARIANT;
   }
 
@@ -1099,6 +1138,6 @@
     hr = S_OK;
   }
-  
-  TRACE("HRESULT = %08lx", hr);
+
+  TRACE("HRESULT = %08lx\n", hr);
   return hr;
 }
Index: trunk/src/oleaut32/stubs.cpp
===================================================================
--- trunk/src/oleaut32/stubs.cpp	(revision 6942)
+++ trunk/src/oleaut32/stubs.cpp	(revision 6944)
@@ -1,3 +1,3 @@
-/* $Id: stubs.cpp,v 1.11 2001-08-23 18:11:21 sandervl Exp $ */
+/* $Id: stubs.cpp,v 1.12 2001-10-03 19:21:59 sandervl Exp $ */
 /* 
  * Win32 COM/OLE stubs for OS/2
@@ -12,37 +12,4 @@
 
 #include "oleaut32.h"
-
-//*****************************************************************************
-//*****************************************************************************
-HRESULT WIN32API DllCanUnloadNow()
-{
-    dprintf(("OLEAUT32: DllCanUnloadNow - stub"));
-    return S_OK;
-}
-
-//*****************************************************************************
-//*****************************************************************************
-HRESULT WIN32API DllRegisterServer(void )
-{
-    dprintf(("OLEAUT32: DllRegisterServer - stub"));
-    return S_OK;
-}
-
-//*****************************************************************************
-//*****************************************************************************
-HRESULT WIN32API DllUnregisterServer(void )
-{
-    dprintf(("OLEAUT32: DllUnregisterServer - stub"));
-    return S_OK;
-}
-
-//*****************************************************************************
-//*****************************************************************************
-HRESULT WIN32API DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID * ppv)
-{
-    dprintf(("OLEAUT32: DllGetClassObject - stub"));
-    return S_OK;
-}
-
 
 //*****************************************************************************
Index: trunk/src/oleaut32/typelib.c
===================================================================
--- trunk/src/oleaut32/typelib.c	(revision 6942)
+++ trunk/src/oleaut32/typelib.c	(revision 6944)
@@ -55,10 +55,11 @@
 #include "winreg.h"         /* for HKEY_LOCAL_MACHINE */
 
+#include "wine/unicode.h"
 #include "wine/obj_base.h"
 #include "heap.h"
 #include "ole2disp.h"
 #include "typelib.h"
-
 #include "debugtools.h"
+#include "ntddk.h"
 
 DEFAULT_DEBUG_CHANNEL(ole);
@@ -251,5 +252,4 @@
 }
 #endif
-
 /******************************************************************************
  *		LoadTypeLib	[OLEAUT32.161]
@@ -263,5 +263,5 @@
  *    Failure: Status
  */
-int TLB_ReadTypeLib(PCHAR file, ITypeLib2 **ppTypelib);
+int TLB_ReadTypeLib(LPCWSTR file, INT index, ITypeLib2 **ppTypelib);
 
 HRESULT WINAPI LoadTypeLib(
@@ -286,15 +286,33 @@
     ITypeLib **pptLib) /* [out] Pointer to pointer to loaded type library */
 {
-    LPSTR p=NULL;
-    WCHAR szPath[MAX_PATH+1];
+    WCHAR szPath[MAX_PATH+1], szFileCopy[MAX_PATH+1];
+    const WCHAR *pFile, *pIndexStr;
     HRESULT res;
+    INT index = 1;
     TRACE("(%s,%d,%p)\n",debugstr_w(szFile), regkind, pptLib);
     
-    if(!SearchPathW(NULL,szFile,NULL,sizeof(szPath)/sizeof(WCHAR),szPath,NULL))
-      res = TYPE_E_CANTLOADLIBRARY;
-    else {
-      p=HEAP_strdupWtoA(GetProcessHeap(),0,szPath);
-      res= TLB_ReadTypeLib(p, (ITypeLib2**)pptLib);
-    }
+    pFile = szFile;
+    if(!SearchPathW(NULL,szFile,NULL,sizeof(szPath)/sizeof(WCHAR),szPath,
+		    NULL)) {
+
+        /* Look for a trailing '\\' followed by an index */
+        pIndexStr = strrchrW(szFile, '\\');
+	if(pIndexStr && pIndexStr != szFile && *++pIndexStr != '\0') {
+	    index = wcstol(pIndexStr, NULL, 10);
+	    memcpy(szFileCopy, szFile,
+		   (pIndexStr - szFile - 1) * sizeof(WCHAR));
+	    szFileCopy[pIndexStr - szFile - 1] = '\0';
+	    pFile = szFileCopy;
+	    if(!SearchPathW(NULL,szFileCopy,NULL,sizeof(szPath)/sizeof(WCHAR),
+			    szPath,NULL))
+	        return TYPE_E_CANTLOADLIBRARY;
+	} else
+	    return TYPE_E_CANTLOADLIBRARY;
+    }
+
+    TRACE("File %s index %d\n", debugstr_w(pFile), index);
+
+    res = TLB_ReadTypeLib(pFile, index, (ITypeLib2**)pptLib);
+
     if (SUCCEEDED(res))
         switch(regkind)
@@ -318,5 +336,4 @@
         }
 
-    if(p) HeapFree(GetProcessHeap(),0,p);
     TRACE(" returns %08lx\n",res);
     return res;
@@ -372,4 +389,7 @@
     CHAR keyName[120];
     HKEY key, subKey;
+    UINT types, tidx;
+    TYPEKIND kind;
+    static const char *PSOA = "{00020424-0000-0000-C000-000000000046}";
 
     if (ptlib == NULL || szFullPath == NULL)
@@ -381,11 +401,6 @@
     StringFromGUID2(&attr->guid, guid, 80);
     guidA = HEAP_strdupWtoA(GetProcessHeap(), 0, guid);
-#ifdef __WIN32OS2__
-    sprintf(keyName, "TypeLib\\%s\\%x.%x",
-            guidA, attr->wMajorVerNum, attr->wMinorVerNum);
-#else
     snprintf(keyName, sizeof(keyName), "TypeLib\\%s\\%x.%x",
         guidA, attr->wMajorVerNum, attr->wMinorVerNum);
-#endif
     HeapFree(GetProcessHeap(), 0, guidA);
 
@@ -425,9 +440,5 @@
             CHAR buf[20];
             /* FIXME: is %u correct? */
-#ifdef __WIN32OS2__
-            sprintf(buf, "%u", attr->wLibFlags);
-#else
             snprintf(buf, sizeof(buf), "%u", attr->wLibFlags);
-#endif
             if (RegSetValueExA(subKey, NULL, 0, REG_SZ,
                 buf, lstrlenA(buf) + 1) != ERROR_SUCCESS)
@@ -439,5 +450,88 @@
         res = E_FAIL;
 
+    /* register OLE Automation-compatible interfaces for this typelib */
+    types = ITypeLib_GetTypeInfoCount(ptlib);
+    for (tidx=0; tidx<types; tidx++) {
+	if (SUCCEEDED(ITypeLib_GetTypeInfoType(ptlib, tidx, &kind))) {
+	    LPOLESTR name = NULL;
+	    ITypeInfo *tinfo = NULL;
+	    BOOL stop = FALSE;
+	    ITypeLib_GetDocumentation(ptlib, tidx, &name, NULL, NULL, NULL);
+	    switch (kind) {
+	    case TKIND_INTERFACE:
+		TRACE_(typelib)("%d: interface %s\n", tidx, debugstr_w(name));
+		ITypeLib_GetTypeInfo(ptlib, tidx, &tinfo);
+		break;
+	    case TKIND_DISPATCH:
+		TRACE_(typelib)("%d: dispinterface %s\n", tidx, debugstr_w(name));
+		/* ITypeLib_GetTypeInfo(ptlib, tidx, &tinfo); */
+		break;
+	    case TKIND_COCLASS:
+		TRACE_(typelib)("%d: coclass %s\n", tidx, debugstr_w(name));
+		/* coclasses should probably not be registered? */
+		break;
+	    default:
+		TRACE_(typelib)("%d: %s\n", tidx, debugstr_w(name));
+		break;
+	    }
+	    if (tinfo) {
+		TYPEATTR *tattr = NULL;
+		ITypeInfo_GetTypeAttr(tinfo, &tattr);
+		if (tattr) {
+		    TRACE_(typelib)("guid=%s, flags=%04x\n",
+				    debugstr_guid(&tattr->guid),
+				    tattr->wTypeFlags);
+		    if (tattr->wTypeFlags & TYPEFLAG_FOLEAUTOMATION) {
+			/* register interface<->typelib coupling */
+			StringFromGUID2(&tattr->guid, guid, 80);
+			guidA = HEAP_strdupWtoA(GetProcessHeap(), 0, guid);
+			snprintf(keyName, sizeof(keyName), "Interface\\%s", guidA);
+			HeapFree(GetProcessHeap(), 0, guidA);
+
+			if (RegCreateKeyExA(HKEY_CLASSES_ROOT, keyName, 0, NULL, 0,
+					    KEY_WRITE, NULL, &key, NULL) == ERROR_SUCCESS) {
+			    if (name)
+				RegSetValueExW(key, NULL, 0, REG_SZ,
+					       (BYTE *)name, lstrlenW(name) * sizeof(OLECHAR));
+
+			    if (RegCreateKeyExA(key, "ProxyStubClsid", 0, NULL, 0,
+				KEY_WRITE, NULL, &subKey, NULL) == ERROR_SUCCESS) {
+				RegSetValueExA(subKey, NULL, 0, REG_SZ,
+					       PSOA, strlen(PSOA));
+				RegCloseKey(subKey);
+			    }
+			    if (RegCreateKeyExA(key, "ProxyStubClsid32", 0, NULL, 0,
+				KEY_WRITE, NULL, &subKey, NULL) == ERROR_SUCCESS) {
+				RegSetValueExA(subKey, NULL, 0, REG_SZ,
+					       PSOA, strlen(PSOA));
+				RegCloseKey(subKey);
+			    }
+
+			    if (RegCreateKeyExA(key, "TypeLib", 0, NULL, 0,
+				KEY_WRITE, NULL, &subKey, NULL) == ERROR_SUCCESS) {
+				CHAR ver[32];
+				StringFromGUID2(&attr->guid, guid, 80);
+				snprintf(ver, sizeof(ver), "%x.%x",
+					 attr->wMajorVerNum, attr->wMinorVerNum);
+				RegSetValueExW(subKey, NULL, 0, REG_SZ,
+					       (BYTE *)guid, lstrlenW(guid) * sizeof(OLECHAR));
+				RegSetValueExA(subKey, "Version", 0, REG_SZ,
+					       ver, lstrlenA(ver));
+				RegCloseKey(subKey);
+			    }
+			    RegCloseKey(key);
+			}
+		    }
+		    ITypeInfo_ReleaseTypeAttr(tinfo, tattr);
+		}
+		ITypeInfo_Release(tinfo);
+	    }
+	    SysFreeString(name);
+	    if (stop) break;
+	}
+    }
+
     ITypeLib_ReleaseTLibAttr(ptlib, attr);
+
     return res;
 }
@@ -464,5 +558,5 @@
 }
 
-#ifndef __WIN32OS2__
+#ifdef __WIN32OS2__
 /****************************************************************************
  *	OaBuildVersion				(TYPELIB.15)
@@ -1761,66 +1855,16 @@
 #define MSFT_SIGNATURE 0x5446534D /* "MSFT" */
 #define SLTG_SIGNATURE 0x47544c53 /* "SLTG" */
-int TLB_ReadTypeLib(LPSTR pszFileName, ITypeLib2 **ppTypeLib)
-{
-    int ret = E_FAIL;
+int TLB_ReadTypeLib(LPCWSTR pszFileName, INT index, ITypeLib2 **ppTypeLib)
+{
+    int ret = TYPE_E_CANTLOADLIBRARY;
     DWORD dwSignature = 0;
     HFILE hFile;
-    int nStrLen = strlen(pszFileName);
-    int i;
-
-    PCHAR pszTypeLibIndex = NULL;
-    PCHAR pszDllName      = NULL;
-
-    TRACE_(typelib)("%s\n", pszFileName);
+
+    TRACE_(typelib)("%s:%d\n", debugstr_w(pszFileName), index);
 
     *ppTypeLib = NULL;
 
-    /* is it a DLL? */
-	for (i=0 ; i < nStrLen ; ++i)
-	{
-	    pszFileName[i] = tolower(pszFileName[i]);
-	}
-    pszTypeLibIndex = strstr(pszFileName, ".dll");
-
-    /* find if there's a back-slash after .DLL (good sign of the presence of a typelib index) */
-    if (pszTypeLibIndex)
-    {
-      pszTypeLibIndex = strstr(pszTypeLibIndex, "\\");
-    }
-
-    /* is there any thing after trailing back-slash  ? */
-    if (pszTypeLibIndex && pszTypeLibIndex < pszFileName + nStrLen)
-    {
-      /* yes -> it's an index! store DLL name, without the trailing back-slash */
-      size_t nMemToAlloc = pszTypeLibIndex - pszFileName;
-      
-      pszDllName = HeapAlloc(GetProcessHeap(),
-                          HEAP_ZERO_MEMORY, 
-                          nMemToAlloc + 1);
-                          
-      strncpy(pszDllName, pszFileName, nMemToAlloc);
-      
-      /* move index string pointer pass the backslash */
-      while (*pszTypeLibIndex == '\\')
-        ++pszTypeLibIndex;
-    }
-    else
-    {
-      /* No index, reset variable to 1 */
-      pszDllName = HeapAlloc(GetProcessHeap(),
-                          HEAP_ZERO_MEMORY, 
-                          nStrLen + 1);
-                          
-      strncpy(pszDllName, pszFileName, nStrLen);
-      
-      pszTypeLibIndex = "1\0";
-    }
-
-    TRACE_(typelib)("File name without index %s\n", pszDllName);
-    TRACE_(typelib)("Index of typelib %s\n",        pszTypeLibIndex);
-
-
     /* check the signature of the file */
-    hFile = CreateFileA( pszDllName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0 );
+    hFile = CreateFileW( pszFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0 );
     if (INVALID_HANDLE_VALUE != hFile)
     {
@@ -1856,9 +1900,10 @@
     {
       /* find the typelibrary resource*/
-      HINSTANCE hinstDLL = LoadLibraryExA(pszDllName, 0, DONT_RESOLVE_DLL_REFERENCES|
+      HINSTANCE hinstDLL = LoadLibraryExW(pszFileName, 0, DONT_RESOLVE_DLL_REFERENCES|
                                           LOAD_LIBRARY_AS_DATAFILE|LOAD_WITH_ALTERED_SEARCH_PATH);
       if (hinstDLL)
       {
-        HRSRC hrsrc = FindResourceA(hinstDLL, MAKEINTRESOURCEA(atoi(pszTypeLibIndex)), "TYPELIB");
+        HRSRC hrsrc = FindResourceA(hinstDLL, MAKEINTRESOURCEA(index),
+	  "TYPELIB");
         if (hrsrc)
         {
@@ -1895,10 +1940,9 @@
     }
 
-    HeapFree(GetProcessHeap(), 0, pszDllName);
-
     if(*ppTypeLib)
       ret = S_OK;
     else
-      ERR("Loading of typelib %s failed with error 0x%08lx\n", pszFileName, GetLastError());
+      ERR("Loading of typelib %s failed with error 0x%08lx\n",
+	  debugstr_w(pszFileName), GetLastError());
 
     return ret;
@@ -2486,21 +2530,27 @@
 	for(param = 0; param < (*ppFuncDesc)->funcdesc.cParams; param++) {
 	    char *paramName = pNameTable + *pArg;
-	    /* right, if the arg type follows then paramName points to the 2nd
-	       letter of the name (or there is no name), else if the next
-	       WORD is an offset to the arg type then paramName points to the
-	       first letter. Before the name there always seems to be the byte
-	       0xff or 0x00, so let's take one char off paramName and see what
-	       we're pointing at.  Got that? */
-
-	    if(*pArg == 0xffff) /* If we don't have a name the type seems to
-				   always follow.  FIXME is this correct? */
-	      paramName = NULL;
+	    BOOL HaveOffs;
+	    /* If arg type follows then paramName points to the 2nd
+	       letter of the name, else the next WORD is an offset to
+	       the arg type and paramName points to the first letter.
+	       So let's take one char off paramName and see if we're
+	       pointing at an alpha-numeric char.  However if *pArg is
+	       0xffff or 0xfffe then the param has no name, the former
+	       meaning that the next WORD is the type, the latter
+	       meaning the the next WORD is an offset to the type. */
+
+	    HaveOffs = FALSE;
+	    if(*pArg == 0xffff)
+	        paramName = NULL;
+	    else if(*pArg == 0xfffe) {
+	        paramName = NULL;
+		HaveOffs = TRUE;
+	    }
+	    else if(!isalnum(*(paramName-1)))
+	        HaveOffs = TRUE;
 
 	    pArg++;
 
-	    if(paramName &&
-	       (*(paramName-1) == '\xff' ||
-	        *(paramName-1) == '\x00')) { /* the next word is an offset to
-					      the type */
+	    if(HaveOffs) { /* the next word is an offset to type */
 	        pType = (WORD*)(pFirstItem + *pArg);
 		SLTG_DoType(pType, pFirstItem,
@@ -2601,5 +2651,5 @@
       if(pItem->magic != SLTG_ENUMITEM_MAGIC) {
 	  FIXME("enumitem magic = %04x\n", pItem->magic);
-	  return;
+	  return NULL;
       }
       *ppVarDesc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
Index: trunk/src/oleaut32/variant.c
===================================================================
--- trunk/src/oleaut32/variant.c	(revision 6942)
+++ trunk/src/oleaut32/variant.c	(revision 6944)
@@ -48,4 +48,6 @@
 DEFAULT_DEBUG_CHANNEL(ole);
 
+#define SYSDUPSTRING(str) SysAllocStringLen((str), SysStringLen(str))
+
 #ifndef FLT_MAX
 # ifdef MAXFLOAT
@@ -90,5 +92,5 @@
  * 400 then it is a leap year.
  */
-/* According to postgeSQL date parsing functions there is
+/* According to postgreSQL date parsing functions there is
  * a leap year when this expression is true.
  * (((y % 4) == 0) && (((y % 100) != 0) || ((y % 400) == 0)))
@@ -104,4 +106,5 @@
  */
 static const double DAYS_IN_ONE_YEAR = 365.2425;
+
 
 /******************************************************************************
@@ -235,90 +238,88 @@
 static BOOL TmToDATE( struct tm* pTm, DATE *pDateOut )
 {
-	if( (pTm->tm_year - 1900) >= 0 )
-	{
-		int leapYear = 0;
-		
-		/* Start at 1. This is the way DATE is defined.
-		 * January 1, 1900 at Midnight is 1.00.
-		 * January 1, 1900 at 6AM is 1.25.
-		 * and so on.
-		 */
-		*pDateOut = 1;
-
-		/* Add the number of days corresponding to
-		 * tm_year.
-		 */
-		*pDateOut += (pTm->tm_year - 1900) * 365;
-
-		/* Add the leap days in the previous years between now and 1900.
-		 * Note a leap year is one that is a multiple of 4
-		 * but not of a 100.  Except if it is a multiple of
-		 * 400 then it is a leap year.
-		 */
-		*pDateOut += ( (pTm->tm_year - 1) / 4 ) - ( 1900 / 4 );
-		*pDateOut -= ( (pTm->tm_year - 1) / 100 ) - ( 1900 / 100 );
-		*pDateOut += ( (pTm->tm_year - 1) / 400 ) - ( 1900 / 400 );
-
-		/* Set the leap year flag if the
-		 * current year specified by tm_year is a
-		 * leap year. This will be used to add a day
-		 * to the day count.
-		 */
-		if( isleap( pTm->tm_year ) )
-			leapYear = 1;
-		
-		/* Add the number of days corresponding to
-		 * the month.
-		 */
-		switch( pTm->tm_mon )
-		{
-		case 2:
-			*pDateOut += 31;
-			break;
-		case 3:
-			*pDateOut += ( 59 + leapYear );
-			break;
-		case 4:
-			*pDateOut += ( 90 + leapYear );
-			break;
-		case 5:
-			*pDateOut += ( 120 + leapYear );
-			break;
-		case 6:
-			*pDateOut += ( 151 + leapYear );
-			break;
-		case 7:
-			*pDateOut += ( 181 + leapYear );
-			break;
-		case 8:
-			*pDateOut += ( 212 + leapYear );
-			break;
-		case 9:
-			*pDateOut += ( 243 + leapYear );
-			break;
-		case 10:
-			*pDateOut += ( 273 + leapYear );
-			break;
-		case 11:
-			*pDateOut += ( 304 + leapYear );
-			break;
-		case 12:
-			*pDateOut += ( 334 + leapYear );
-			break;
-		}
-		/* Add the number of days in this month.
-		 */
-		*pDateOut += pTm->tm_mday;
-	
-		/* Add the number of seconds, minutes, and hours
-		 * to the DATE. Note these are the fracionnal part
-		 * of the DATE so seconds / number of seconds in a day.
-		 */
-		*pDateOut += pTm->tm_hour / 24.0;
-		*pDateOut += pTm->tm_min / 1440.0;
-		*pDateOut += pTm->tm_sec / 86400.0;
-		return TRUE;
-	}
-	return FALSE;
+    int leapYear = 0;
+
+    if( (pTm->tm_year - 1900) < 0 ) return FALSE;
+
+    /* Start at 1. This is the way DATE is defined.
+     * January 1, 1900 at Midnight is 1.00.
+     * January 1, 1900 at 6AM is 1.25.
+     * and so on.
+     */
+    *pDateOut = 1;
+
+    /* Add the number of days corresponding to
+     * tm_year.
+     */
+    *pDateOut += (pTm->tm_year - 1900) * 365;
+
+    /* Add the leap days in the previous years between now and 1900.
+     * Note a leap year is one that is a multiple of 4
+     * but not of a 100.  Except if it is a multiple of
+     * 400 then it is a leap year.
+     */
+    *pDateOut += ( (pTm->tm_year - 1) / 4 ) - ( 1900 / 4 );
+    *pDateOut -= ( (pTm->tm_year - 1) / 100 ) - ( 1900 / 100 );
+    *pDateOut += ( (pTm->tm_year - 1) / 400 ) - ( 1900 / 400 );
+
+    /* Set the leap year flag if the
+     * current year specified by tm_year is a
+     * leap year. This will be used to add a day
+     * to the day count.
+     */
+    if( isleap( pTm->tm_year ) )
+        leapYear = 1;
+
+    /* Add the number of days corresponding to
+     * the month.
+     */
+    switch( pTm->tm_mon )
+    {
+    case 2:
+        *pDateOut += 31;
+        break;
+    case 3:
+        *pDateOut += ( 59 + leapYear );
+        break;
+    case 4:
+        *pDateOut += ( 90 + leapYear );
+        break;
+    case 5:
+        *pDateOut += ( 120 + leapYear );
+        break;
+    case 6:
+        *pDateOut += ( 151 + leapYear );
+        break;
+    case 7:
+        *pDateOut += ( 181 + leapYear );
+        break;
+    case 8:
+        *pDateOut += ( 212 + leapYear );
+        break;
+    case 9:
+        *pDateOut += ( 243 + leapYear );
+        break;
+    case 10:
+        *pDateOut += ( 273 + leapYear );
+        break;
+    case 11:
+        *pDateOut += ( 304 + leapYear );
+        break;
+    case 12:
+        *pDateOut += ( 334 + leapYear );
+        break;
+    }
+    /* Add the number of days in this month.
+     */
+    *pDateOut += pTm->tm_mday;
+
+    /* Add the number of seconds, minutes, and hours
+     * to the DATE. Note these are the fracionnal part
+     * of the DATE so seconds / number of seconds in a day.
+     */
+    *pDateOut += pTm->tm_hour / 24.0;
+    *pDateOut += pTm->tm_min / 1440.0;
+    *pDateOut += pTm->tm_sec / 86400.0;
+    return TRUE;
 }
 
@@ -339,130 +340,128 @@
 static BOOL DateToTm( DATE dateIn, DWORD dwFlags, struct tm* pTm )
 {
-	/* Do not process dates smaller than January 1, 1900.
-	 * Which corresponds to 2.0 in the windows DATE format.
-	 */
-	if( dateIn >= 2.0 )
-	{
-		double decimalPart = 0.0;
-		double wholePart = 0.0;
-
-		memset(pTm,0,sizeof(*pTm));
-	
-		/* Because of the nature of DATE format which
-		 * associates 2.0 to January 1, 1900. We will
-		 * remove 1.0 from the whole part of the DATE
-		 * so that in the following code 1.0
-		 * will correspond to January 1, 1900.
-		 * This simplifies the processing of the DATE value.
-		 */
-		dateIn -= 1.0;
-
-		wholePart = (double) floor( dateIn );
-		decimalPart = fmod( dateIn, wholePart );
-
-		if( !(dwFlags & VAR_TIMEVALUEONLY) )
-		{
-			int nDay = 0;
-			int leapYear = 0;
-			double yearsSince1900 = 0;
-			/* Start at 1900, this is where the DATE time 0.0 starts.
-			 */
-			pTm->tm_year = 1900;
-			/* find in what year the day in the "wholePart" falls into.
-			 * add the value to the year field.
-			 */
-			yearsSince1900 = floor( (wholePart / DAYS_IN_ONE_YEAR) + 0.001 );
-			pTm->tm_year += yearsSince1900;
-			/* determine if this is a leap year.
-			 */
-			if( isleap( pTm->tm_year ) )
-			{
-				leapYear = 1;
-				wholePart++;
-			}
-
-			/* find what day of that year the "wholePart" corresponds to.
-			 * Note: nDay is in [1-366] format
-			 */
-			nDay = (int) ( wholePart - floor( yearsSince1900 * DAYS_IN_ONE_YEAR ) );
-			/* Set the tm_yday value.
-			 * Note: The day must be converted from [1-366] to [0-365]
-			 */
-			/*pTm->tm_yday = nDay - 1;*/
-			/* find which month this day corresponds to.
-			 */
-			if( nDay <= 31 )
-			{
-				pTm->tm_mday = nDay;
-				pTm->tm_mon = 0;
-			}
-			else if( nDay <= ( 59 + leapYear ) )
-			{
-				pTm->tm_mday = nDay - 31;
-				pTm->tm_mon = 1;
-			}
-			else if( nDay <= ( 90 + leapYear ) )
-			{
-				pTm->tm_mday = nDay - ( 59 + leapYear );
-				pTm->tm_mon = 2;
-			}
-			else if( nDay <= ( 120 + leapYear ) )
-			{
-				pTm->tm_mday = nDay - ( 90 + leapYear );
-				pTm->tm_mon = 3;
-			}
-			else if( nDay <= ( 151 + leapYear ) )
-			{
-				pTm->tm_mday = nDay - ( 120 + leapYear );
-				pTm->tm_mon = 4;
-			}
-			else if( nDay <= ( 181 + leapYear ) )
-			{
-				pTm->tm_mday = nDay - ( 151 + leapYear );
-				pTm->tm_mon = 5;
-			}
-			else if( nDay <= ( 212 + leapYear ) )
-			{
-				pTm->tm_mday = nDay - ( 181 + leapYear );
-				pTm->tm_mon = 6;
-			}
-			else if( nDay <= ( 243 + leapYear ) )
-			{
-				pTm->tm_mday = nDay - ( 212 + leapYear );
-				pTm->tm_mon = 7;
-			}
-			else if( nDay <= ( 273 + leapYear ) )
-			{
-				pTm->tm_mday = nDay - ( 243 + leapYear );
-				pTm->tm_mon = 8;
-			}
-			else if( nDay <= ( 304 + leapYear ) )
-			{
-				pTm->tm_mday = nDay - ( 273 + leapYear );
-				pTm->tm_mon = 9;
-			}
-			else if( nDay <= ( 334 + leapYear ) )
-			{
-				pTm->tm_mday = nDay - ( 304 + leapYear );
-				pTm->tm_mon = 10;
-			}
-			else if( nDay <= ( 365 + leapYear ) )
-			{
-				pTm->tm_mday = nDay - ( 334 + leapYear );
-				pTm->tm_mon = 11;
-			}
-		}
-		if( !(dwFlags & VAR_DATEVALUEONLY) )
-		{
-			/* find the number of seconds in this day.
-			 * fractional part times, hours, minutes, seconds.
-			 */
-			pTm->tm_hour = (int) ( decimalPart * 24 );
-			pTm->tm_min = (int) ( ( ( decimalPart * 24 ) - pTm->tm_hour ) * 60 );
-			pTm->tm_sec = (int) ( ( ( decimalPart * 24 * 60 ) - ( pTm->tm_hour * 60 ) - pTm->tm_min ) * 60 );
-		}
-		return TRUE;
-	}
-	return FALSE;
+    double decimalPart = 0.0;
+    double wholePart = 0.0;
+
+    /* Do not process dates smaller than January 1, 1900.
+     * Which corresponds to 2.0 in the windows DATE format.
+     */
+    if( dateIn < 2.0 ) return FALSE;
+
+    memset(pTm,0,sizeof(*pTm));
+
+    /* Because of the nature of DATE format which
+     * associates 2.0 to January 1, 1900. We will
+     * remove 1.0 from the whole part of the DATE
+     * so that in the following code 1.0
+     * will correspond to January 1, 1900.
+     * This simplifies the processing of the DATE value.
+     */
+    dateIn -= 1.0;
+
+    wholePart = (double) floor( dateIn );
+    decimalPart = fmod( dateIn, wholePart );
+
+    if( !(dwFlags & VAR_TIMEVALUEONLY) )
+    {
+        int nDay = 0;
+        int leapYear = 0;
+        double yearsSince1900 = 0;
+        /* Start at 1900, this is where the DATE time 0.0 starts.
+         */
+        pTm->tm_year = 1900;
+        /* find in what year the day in the "wholePart" falls into.
+         * add the value to the year field.
+         */
+        yearsSince1900 = floor( (wholePart / DAYS_IN_ONE_YEAR) + 0.001 );
+        pTm->tm_year += yearsSince1900;
+        /* determine if this is a leap year.
+         */
+        if( isleap( pTm->tm_year ) )
+        {
+            leapYear = 1;
+            wholePart++;
+        }
+
+        /* find what day of that year the "wholePart" corresponds to.
+         * Note: nDay is in [1-366] format
+         */
+        nDay = (int) ( wholePart - floor( yearsSince1900 * DAYS_IN_ONE_YEAR ) );
+        /* Set the tm_yday value.
+         * Note: The day must be converted from [1-366] to [0-365]
+         */
+        /*pTm->tm_yday = nDay - 1;*/
+        /* find which month this day corresponds to.
+         */
+        if( nDay <= 31 )
+        {
+            pTm->tm_mday = nDay;
+            pTm->tm_mon = 0;
+        }
+        else if( nDay <= ( 59 + leapYear ) )
+        {
+            pTm->tm_mday = nDay - 31;
+            pTm->tm_mon = 1;
+        }
+        else if( nDay <= ( 90 + leapYear ) )
+        {
+            pTm->tm_mday = nDay - ( 59 + leapYear );
+            pTm->tm_mon = 2;
+        }
+        else if( nDay <= ( 120 + leapYear ) )
+        {
+            pTm->tm_mday = nDay - ( 90 + leapYear );
+            pTm->tm_mon = 3;
+        }
+        else if( nDay <= ( 151 + leapYear ) )
+        {
+            pTm->tm_mday = nDay - ( 120 + leapYear );
+            pTm->tm_mon = 4;
+        }
+        else if( nDay <= ( 181 + leapYear ) )
+        {
+            pTm->tm_mday = nDay - ( 151 + leapYear );
+            pTm->tm_mon = 5;
+        }
+        else if( nDay <= ( 212 + leapYear ) )
+        {
+            pTm->tm_mday = nDay - ( 181 + leapYear );
+            pTm->tm_mon = 6;
+        }
+        else if( nDay <= ( 243 + leapYear ) )
+        {
+            pTm->tm_mday = nDay - ( 212 + leapYear );
+            pTm->tm_mon = 7;
+        }
+        else if( nDay <= ( 273 + leapYear ) )
+        {
+            pTm->tm_mday = nDay - ( 243 + leapYear );
+            pTm->tm_mon = 8;
+        }
+        else if( nDay <= ( 304 + leapYear ) )
+        {
+            pTm->tm_mday = nDay - ( 273 + leapYear );
+            pTm->tm_mon = 9;
+        }
+        else if( nDay <= ( 334 + leapYear ) )
+        {
+            pTm->tm_mday = nDay - ( 304 + leapYear );
+            pTm->tm_mon = 10;
+        }
+        else if( nDay <= ( 365 + leapYear ) )
+        {
+            pTm->tm_mday = nDay - ( 334 + leapYear );
+            pTm->tm_mon = 11;
+        }
+    }
+    if( !(dwFlags & VAR_DATEVALUEONLY) )
+    {
+        /* find the number of seconds in this day.
+         * fractional part times, hours, minutes, seconds.
+         */
+        pTm->tm_hour = (int) ( decimalPart * 24 );
+        pTm->tm_min = (int) ( ( ( decimalPart * 24 ) - pTm->tm_hour ) * 60 );
+        pTm->tm_sec = (int) ( ( ( decimalPart * 24 * 60 ) - ( pTm->tm_hour * 60 ) - pTm->tm_min ) * 60 );
+    }
+    return TRUE;
 }
 
@@ -615,5 +614,4 @@
 	LPSTR pNewString = NULL;
 	LPSTR strToken = NULL;
-
 
 	/* Check if we have a valid argument
@@ -1680,10 +1678,10 @@
  *		VariantInit	[OLEAUT32.8]
  *
- * Initializes the Variant.  Unlike VariantClear it does not interpret the current
- * contents of the Variant.
+ * Initializes the Variant.  Unlike VariantClear it does not interpret
+ * the current contents of the Variant.
  */
 void WINAPI VariantInit(VARIANTARG* pvarg)
 {
-  TRACE("(%p),stub\n",pvarg);
+  TRACE("(%p)\n",pvarg);
 
   memset(pvarg, 0, sizeof (VARIANTARG));
@@ -1764,5 +1762,5 @@
   HRESULT res = S_OK;
 
-  TRACE("(%p, %p)\n", pvargDest, pvargSrc);
+  TRACE("(%p, %p), vt=%d\n", pvargDest, pvargSrc, V_VT(pvargSrc));
 
   res = ValidateVariantType( V_VT(pvargSrc) );
@@ -1797,7 +1795,7 @@
 	{
 	  /* In the case of by value we need to
-	   * copy the actuall value. In the case of
+	   * copy the actual value. In the case of
 	   * VT_BSTR a copy of the string is made,
-	   * if VT_DISPATCH or VT_IUNKNOWN AddReff is
+	   * if VT_DISPATCH or VT_IUNKNOWN AddRef is
 	   * called to increment the object's reference count.
 	   */
@@ -1805,5 +1803,5 @@
 	  {
 	    case( VT_BSTR ):
-	      V_UNION(pvargDest,bstrVal) = SysAllocString( V_UNION(pvargSrc,bstrVal) );
+	      V_UNION(pvargDest,bstrVal) = SYSDUPSTRING( V_UNION(pvargSrc,bstrVal) );
 	      break;
 	    case( VT_DISPATCH ):
@@ -1894,5 +1892,5 @@
 	  {
 	    case( VT_BSTR ):
-	      V_UNION(pvargDest,bstrVal) = SysAllocString( *(V_UNION(pvargSrc,pbstrVal)) );
+	      V_UNION(pvargDest,bstrVal) = SYSDUPSTRING( *(V_UNION(pvargSrc,pbstrVal)) );
 	      break;
 	    case( VT_DISPATCH ):
@@ -1986,5 +1984,5 @@
 	VariantInit( &varg );
 	
-	TRACE("(%p, %p, %ld, %u, %u),stub\n", pvargDest, pvargSrc, lcid, wFlags, vt);
+	TRACE("(%p, %p, %ld, %u, %u) vt=%d\n", pvargDest, pvargSrc, lcid, wFlags, vt, V_VT(pvargSrc));
 
 	/* validate our source argument.
@@ -3251,5 +3249,5 @@
  */
 HRESULT WINAPI VarBstrFromCy(CY cyIn, LCID lcid, ULONG dwFlags, BSTR *pbstrOut) {
-				/* FIXME */
+	FIXME("([cyIn], %08lx, %08lx, %p), stub.\n", lcid, dwFlags, pbstrOut);
 	return E_NOTIMPL;
 }
@@ -3316,12 +3314,5 @@
 	TRACE("( %d, %ld, %ld, %p ), stub\n", boolIn, lcid, dwFlags, pbstrOut );
 
-	if( boolIn == VARIANT_FALSE )
-	{
-		sprintf( pBuffer, "False" );
-	}
-	else
-	{
-		sprintf( pBuffer, "True" );
-	}
+	sprintf( pBuffer, (boolIn == VARIANT_FALSE) ? "False" : "True" );
 
 	*pbstrOut = StringDupAtoBstr( pBuffer );
@@ -3392,12 +3383,5 @@
 	TRACE("( %d, %p ), stub\n", sIn, pboolOut );
 
-	if( sIn == 0 )
-	{
-		*pboolOut = VARIANT_FALSE;
-	}
-	else
-	{
-		*pboolOut = VARIANT_TRUE;
-	}
+	*pboolOut = (sIn) ? VARIANT_TRUE : VARIANT_FALSE;
 
 	return S_OK;
@@ -3411,12 +3395,5 @@
 	TRACE("( %ld, %p ), stub\n", lIn, pboolOut );
 
-	if( lIn == 0 )
-	{
-		*pboolOut = VARIANT_FALSE;
-	}
-	else
-	{
-		*pboolOut = VARIANT_TRUE;
-	}
+	*pboolOut = (lIn) ? VARIANT_TRUE : VARIANT_FALSE;
 
 	return S_OK;
@@ -3430,12 +3407,5 @@
 	TRACE("( %f, %p ), stub\n", fltIn, pboolOut );
 
-	if( fltIn == 0.0 )
-	{
-		*pboolOut = VARIANT_FALSE;
-	}
-	else
-	{
-		*pboolOut = VARIANT_TRUE;
-	}
+	*pboolOut = (fltIn == 0.0) ? VARIANT_FALSE : VARIANT_TRUE;
 
 	return S_OK;
@@ -3449,12 +3419,5 @@
 	TRACE("( %f, %p ), stub\n", dblIn, pboolOut );
 
-	if( dblIn == 0.0 )
-	{
-		*pboolOut = VARIANT_FALSE;
-	}
-	else
-	{
-		*pboolOut = VARIANT_TRUE;
-	}
+	*pboolOut = (dblIn == 0.0) ? VARIANT_FALSE : VARIANT_TRUE;
 
 	return S_OK;
@@ -3468,12 +3431,5 @@
 	TRACE("( %f, %p ), stub\n", dateIn, pboolOut );
 
-	if( dateIn == 0.0 )
-	{
-		*pboolOut = VARIANT_FALSE;
-	}
-	else
-	{
-		*pboolOut = VARIANT_TRUE;
-	}
+	*pboolOut = (dateIn == 0.0) ? VARIANT_FALSE : VARIANT_TRUE;
 
 	return S_OK;
@@ -3517,12 +3473,7 @@
 				ret = DISP_E_TYPEMISMATCH;
 			}
-			else if( dValue == 0.0 )
-			{
-				*pboolOut = VARIANT_FALSE;
-			}
 			else
-			{
-				*pboolOut = VARIANT_TRUE;
-			}
+				*pboolOut = (dValue == 0.0) ?
+						VARIANT_FALSE : VARIANT_TRUE;
 		}
 	}
@@ -3540,12 +3491,5 @@
 	TRACE("( %c, %p ), stub\n", cIn, pboolOut );
 
-	if( cIn == 0 )
-	{
-		*pboolOut = VARIANT_FALSE;
-	}
-	else
-	{
-		*pboolOut = VARIANT_TRUE;
-	}
+	*pboolOut = (cIn == 0) ? VARIANT_FALSE : VARIANT_TRUE;
 
 	return S_OK;
@@ -3559,12 +3503,5 @@
 	TRACE("( %d, %p ), stub\n", uiIn, pboolOut );
 
-	if( uiIn == 0 )
-	{
-		*pboolOut = VARIANT_FALSE;
-	}
-	else
-	{
-		*pboolOut = VARIANT_TRUE;
-	}
+	*pboolOut = (uiIn == 0) ? VARIANT_FALSE : VARIANT_TRUE;
 
 	return S_OK;
@@ -3578,12 +3515,5 @@
 	TRACE("( %ld, %p ), stub\n", ulIn, pboolOut );
 
-	if( ulIn == 0 )
-	{
-		*pboolOut = VARIANT_FALSE;
-	}
-	else
-	{
-		*pboolOut = VARIANT_TRUE;
-	}
+	*pboolOut = (ulIn == 0) ? VARIANT_FALSE : VARIANT_TRUE;
 
 	return S_OK;
@@ -4111,9 +4041,9 @@
 	TRACE("( %f, %p ), stub\n", dblIn, pulOut );
 
-    dblIn = round( dblIn );
+	dblIn = round( dblIn );
 	if( dblIn < UI4_MIN || dblIn > UI4_MAX )
 	{
 		return DISP_E_OVERFLOW;
-    }
+	}
 
 	*pulOut = (ULONG) dblIn;
@@ -4129,6 +4059,6 @@
 	TRACE("( %f, %p ), stub\n", dateIn, pulOut );
 
-    dateIn = round( dateIn );
-    if( dateIn < UI4_MIN || dateIn > UI4_MAX )
+	dateIn = round( dateIn );
+	if( dateIn < UI4_MIN || dateIn > UI4_MAX )
 	{
 		return DISP_E_OVERFLOW;
@@ -4195,8 +4125,8 @@
  */
 HRESULT WINAPI VarCyFromUI1(BYTE bIn, CY* pcyOut) {
-   pcyOut->s.Hi = 0;
-   pcyOut->s.Lo = ((ULONG)bIn) * 10000;
-   
-   return S_OK;
+    pcyOut->s.Hi = 0;
+    pcyOut->s.Lo = ((ULONG)bIn) * 10000;
+
+    return S_OK;
 }
 
@@ -4206,9 +4136,9 @@
  */
 HRESULT WINAPI VarCyFromI2(short sIn, CY* pcyOut) {
-   if (sIn < 0) pcyOut->s.Hi = -1;
-   else pcyOut->s.Hi = 0;
-   pcyOut->s.Lo = ((ULONG)sIn) * 10000;
-   
-   return S_OK;
+    if (sIn < 0) pcyOut->s.Hi = -1;
+    else pcyOut->s.Hi = 0;
+    pcyOut->s.Lo = ((ULONG)sIn) * 10000;
+
+    return S_OK;
 }
 
@@ -4269,6 +4199,6 @@
  */
 HRESULT WINAPI VarCyFromStr(OLECHAR *strIn, LCID lcid, ULONG dwFlags, CY *pcyOut) {
-				/* FIXME */
-		return E_NOTIMPL;
+	FIXME("(%p, %08lx, %08lx, %p), stub.\n", strIn, lcid, dwFlags, pcyOut);
+	return E_NOTIMPL;
 }
 
@@ -4414,5 +4344,5 @@
 
 /**********************************************************************
- *              VariantTimeToDosDateTime [OLEAUT32.??]
+ *              VariantTimeToDosDateTime [OLEAUT32.13]
  * Convert variant representation of time to the date and time representation
  * stored in dos.
@@ -4440,4 +4370,7 @@
 
 
+/***********************************************************************
+ *              SystemTimeToVariantTime [OLEAUT32.184]
+ */
 HRESULT WINAPI SystemTimeToVariantTime( LPSYSTEMTIME  lpSystemTime, double *pvtime )
 {
@@ -4488,4 +4421,7 @@
 }
 
+/***********************************************************************
+ *              VariantTimeToSystemTime [OLEAUT32.185]
+ */
 HRESULT WINAPI VariantTimeToSystemTime( double vtime, LPSYSTEMTIME  lpSystemTime )
 {
@@ -4603,4 +4539,7 @@
 }
 
+/***********************************************************************
+ *              VarUdateFromDate [OLEAUT32.331]
+ */
 HRESULT WINAPI VarUdateFromDate( DATE datein, ULONG dwFlags, UDATE *pudateout)
 {
@@ -4635,4 +4574,7 @@
 }
 
+/***********************************************************************
+ *              VarDateFromUdate [OLEAUT32.330]
+ */
 HRESULT WINAPI VarDateFromUdate(UDATE *pudateout,
                                 ULONG dwFlags, DATE *datein)
