Index: trunk/src/ole32/compobj.c
===================================================================
--- trunk/src/ole32/compobj.c	(revision 9394)
+++ trunk/src/ole32/compobj.c	(revision 9400)
@@ -46,75 +46,9 @@
 #include "wine/obj_storage.h"
 #include "wine/obj_channel.h"
-#include "wine/winbase16.h"
 #include "compobj_private.h"
-#include "ifs.h"
 
 #include "wine/debug.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(ole);
-
-/****************************************************************************
- *  COM External Lock structures and methods declaration
- *
- *  This api provides a linked list to managed external references to
- *  COM objects.
- *
- *  The public interface consists of three calls:
- *      COM_ExternalLockAddRef
- *      COM_ExternalLockRelease
- *      COM_ExternalLockFreeList
- */
-
-#define EL_END_OF_LIST 0
-#define EL_NOT_FOUND   0
-
-/*
- * Declaration of the static structure that manage the
- * external lock to COM  objects.
- */
-typedef struct COM_ExternalLock     COM_ExternalLock;
-typedef struct COM_ExternalLockList COM_ExternalLockList;
-
-struct COM_ExternalLock
-{
-  IUnknown         *pUnk;     /* IUnknown referenced */
-  ULONG            uRefCount; /* external lock counter to IUnknown object*/
-  COM_ExternalLock *next;     /* Pointer to next element in list */
-};
-
-struct COM_ExternalLockList
-{
-  COM_ExternalLock *head;     /* head of list */
-};
-
-/*
- * Declaration and initialization of the static structure that manages
- * the external lock to COM objects.
- */
-static COM_ExternalLockList elList = { EL_END_OF_LIST };
-
-/*
- * Public Interface to the external lock list
- */
-static void COM_ExternalLockFreeList();
-static void COM_ExternalLockAddRef(IUnknown *pUnk);
-static void COM_ExternalLockRelease(IUnknown *pUnk, BOOL bRelAll);
-void COM_ExternalLockDump(); /* testing purposes, not static to avoid warning */
-
-/*
- * Private methods used to managed the linked list
- */
-static BOOL COM_ExternalLockInsert(
-  IUnknown *pUnk);
-
-static void COM_ExternalLockDelete(
-  COM_ExternalLock *element);
-
-static COM_ExternalLock* COM_ExternalLockFind(
-  IUnknown *pUnk);
-
-static COM_ExternalLock* COM_ExternalLockLocate(
-  COM_ExternalLock *element,
-  IUnknown         *pUnk);
 
 /****************************************************************************
@@ -123,13 +57,49 @@
  * TODO: Most of these things will have to be made thread-safe.
  */
-HINSTANCE16     COMPOBJ_hInstance = 0;
 HINSTANCE       COMPOBJ_hInstance32 = 0;
-static int      COMPOBJ_Attach = 0;
-
-LPMALLOC16 currentMalloc16=NULL;
-LPMALLOC currentMalloc32=NULL;
-
-HTASK16 hETask = 0;
-WORD Table_ETask[62];
+
+static HRESULT COM_GetRegisteredClassObject(REFCLSID rclsid, DWORD dwClsContext, LPUNKNOWN*  ppUnk);
+static void COM_RevokeAllClasses();
+static void COM_ExternalLockFreeList();
+
+/*****************************************************************************
+ * Appartment management stuff
+ *
+ * NOTE:
+ *  per Thread values are stored in the TEB on offset 0xF80
+ *
+ *  see www.microsoft.com/msj/1099/bugslayer/bugslayer1099.htm
+ *
+ */
+
+typedef struct {
+        unsigned char		threadingModell;	/* we use the COINIT flags */
+        unsigned long		threadID;
+	long			AppartmentLockCount;
+} OleAppartmentData;
+
+typedef struct {
+	OleAppartmentData 	*AppartmentData;
+} OleThreadData;
+
+/* not jet used
+static CRITICAL_SECTION csAppartmentData = CRITICAL_SECTION_INIT("csAppartmentData");
+*/
+/*
+ * the first STA created in a process is the main STA
+ */
+
+/* not jet used
+static OleAppartmentData * mainSTA;
+*/
+
+/*
+ * a Process can only have one MTA
+ */
+
+/* not jet used
+static OleAppartmentData * processMTA;
+*/
+
 
 /*
@@ -159,11 +129,18 @@
 } RegisteredClass;
 
-static CRITICAL_SECTION csRegisteredClassList;
+static CRITICAL_SECTION csRegisteredClassList = CRITICAL_SECTION_INIT("csRegisteredClassList");
 static RegisteredClass* firstRegisteredClass = NULL;
 
-/* this open DLL table belongs in a per process table, but my guess is that
- * it shouldn't live in the kernel, so I'll put them out here in DLL
- * space assuming that there is one OLE32 per process.
- */
+/*****************************************************************************
+ * This section contains OpenDllList definitions
+ *
+ * The OpenDllList contains only handles of dll loaded by CoGetClassObject or
+ * other functions what do LoadLibrary _without_ giving back a HMODULE.
+ * Without this list these handles would be freed never.
+ *
+ * FIXME: a DLL what says OK whenn asked for unloading is unloaded in the
+ * next unload-call but not before 600 sec.
+ */
+
 typedef struct tagOpenDll {
   HINSTANCE hLibrary;
@@ -171,16 +148,9 @@
 } OpenDll;
 
-static CRITICAL_SECTION csOpenDllList;
+static CRITICAL_SECTION csOpenDllList = CRITICAL_SECTION_INIT("csOpenDllList");
 static OpenDll *openDllList = NULL; /* linked list of open dlls */
 
-/*****************************************************************************
- * This section contains prototypes to internal methods for this
- * module
- */
-static HRESULT COM_GetRegisteredClassObject(REFCLSID    rclsid,
-					    DWORD       dwClsContext,
-					    LPUNKNOWN*  ppUnk);
-
-static void COM_RevokeAllClasses();
+static void COMPOBJ_DLLList_Add(HANDLE hLibrary);
+static void COMPOBJ_DllList_FreeUnused(int Timeout);
 
 
@@ -190,12 +160,83 @@
 void COMPOBJ_InitProcess( void )
 {
-    InitializeCriticalSection( &csRegisteredClassList );
-    InitializeCriticalSection( &csOpenDllList );
 }
 
 void COMPOBJ_UninitProcess( void )
 {
-    DeleteCriticalSection( &csRegisteredClassList );
-    DeleteCriticalSection( &csOpenDllList );
+}
+
+/*****************************************************************************
+ * This section contains OpenDllList implemantation
+ */
+
+static void COMPOBJ_DLLList_Add(HANDLE hLibrary)
+{
+    OpenDll *ptr;
+    OpenDll *tmp;
+
+    TRACE("\n");
+
+    EnterCriticalSection( &csOpenDllList );
+
+    if (openDllList == NULL) {
+        /* empty list -- add first node */
+        openDllList = (OpenDll*)HeapAlloc(GetProcessHeap(),0, sizeof(OpenDll));
+	openDllList->hLibrary=hLibrary;
+	openDllList->next = NULL;
+    } else {
+        /* search for this dll */
+        int found = FALSE;
+        for (ptr = openDllList; ptr->next != NULL; ptr=ptr->next) {
+  	    if (ptr->hLibrary == hLibrary) {
+	        found = TRUE;
+		break;
+	    }
+        }
+	if (!found) {
+	    /* dll not found, add it */
+ 	    tmp = openDllList;
+	    openDllList = (OpenDll*)HeapAlloc(GetProcessHeap(),0, sizeof(OpenDll));
+	    openDllList->hLibrary = hLibrary;
+	    openDllList->next = tmp;
+	}
+    }
+
+    LeaveCriticalSection( &csOpenDllList );
+}
+
+static void COMPOBJ_DllList_FreeUnused(int Timeout)
+{
+    OpenDll *curr, *next, *prev = NULL;
+    typedef HRESULT(*DllCanUnloadNowFunc)(void);
+    DllCanUnloadNowFunc DllCanUnloadNow;
+
+    TRACE("\n");
+
+    EnterCriticalSection( &csOpenDllList );
+
+    for (curr = openDllList; curr != NULL; ) {
+	DllCanUnloadNow = (DllCanUnloadNowFunc) GetProcAddress(curr->hLibrary, "DllCanUnloadNow");
+
+	if ( (DllCanUnloadNow != NULL) && (DllCanUnloadNow() == S_OK) ) {
+	    next = curr->next;
+
+	    TRACE("freeing 0x%08x\n", curr->hLibrary);
+	    FreeLibrary(curr->hLibrary);
+
+	    HeapFree(GetProcessHeap(), 0, curr);
+	    if (curr == openDllList) {
+		openDllList = next;
+	    } else {
+	      prev->next = next;
+	    }
+
+	    curr = next;
+	} else {
+	    prev = curr;
+	    curr = curr->next;
+	}
+    }
+
+    LeaveCriticalSection( &csOpenDllList );
 }
 
@@ -211,15 +252,4 @@
     TRACE("Returning version %d, build %d.\n", rmm, rup);
     return (rmm<<16)+rup;
-}
-
-/******************************************************************************
- *		CoInitialize	[COMPOBJ.2]
- * Set the win16 IMalloc used for memory management
- */
-HRESULT WINAPI CoInitialize16(
-	LPVOID lpReserved	/* [in] pointer to win16 malloc interface */
-) {
-    currentMalloc16 = (LPMALLOC16)lpReserved;
-    return S_OK;
 }
 
@@ -306,16 +336,4 @@
 
   return hr;
-}
-
-/***********************************************************************
- *           CoUninitialize   [COMPOBJ.3]
- * Don't know what it does.
- * 3-Nov-98 -- this was originally misspelled, I changed it to what I
- *   believe is the correct spelling
- */
-void WINAPI CoUninitialize16(void)
-{
-  TRACE("()\n");
-  CoFreeAllLibraries();
 }
 
@@ -368,48 +386,4 @@
 }
 
-#ifndef __WIN32OS2__
-/***********************************************************************
- *           CoGetMalloc    [COMPOBJ.4]
- * RETURNS
- *	The current win16 IMalloc
- */
-HRESULT WINAPI CoGetMalloc16(
-	DWORD dwMemContext,	/* [in] unknown */
-	LPMALLOC16 * lpMalloc	/* [out] current win16 malloc interface */
-) {
-    if(!currentMalloc16)
-	currentMalloc16 = IMalloc16_Constructor();
-    *lpMalloc = currentMalloc16;
-    return S_OK;
-}
-#endif
-/******************************************************************************
- *		CoGetMalloc	[OLE32.20]
- *
- * RETURNS
- *	The current win32 IMalloc
- */
-HRESULT WINAPI CoGetMalloc(
-	DWORD dwMemContext,	/* [in] unknown */
-	LPMALLOC *lpMalloc	/* [out] current win32 malloc interface */
-) {
-    if(!currentMalloc32)
-	currentMalloc32 = IMalloc_Constructor();
-    *lpMalloc = currentMalloc32;
-    return S_OK;
-}
-#ifndef __WIN32OS2__
-/***********************************************************************
- *           CoCreateStandardMalloc [COMPOBJ.71]
- */
-HRESULT WINAPI CoCreateStandardMalloc16(DWORD dwMemContext,
-					  LPMALLOC16 *lpMalloc)
-{
-    /* FIXME: docu says we shouldn't return the same allocator as in
-     * CoGetMalloc16 */
-    *lpMalloc = IMalloc16_Constructor();
-    return S_OK;
-}
-#endif
 /******************************************************************************
  *		CoDisconnectObject	[COMPOBJ.15]
@@ -420,113 +394,4 @@
     TRACE("(%p, %lx)\n",lpUnk,reserved);
     return S_OK;
-}
-
-/***********************************************************************
- *           IsEqualGUID [COMPOBJ.18]
- *
- * Compares two Unique Identifiers.
- *
- * RETURNS
- *	TRUE if equal
- */
-BOOL16 WINAPI IsEqualGUID16(
-	GUID* g1,	/* [in] unique id 1 */
-	GUID* g2	/* [in] unique id 2 */
-) {
-    return !memcmp( g1, g2, sizeof(GUID) );
-}
-
-/******************************************************************************
- *		CLSIDFromString	[COMPOBJ.20]
- * Converts a unique identifier from its string representation into
- * the GUID struct.
- *
- * Class id: DWORD-WORD-WORD-BYTES[2]-BYTES[6]
- *
- * RETURNS
- *	the converted GUID
- */
-HRESULT WINAPI CLSIDFromString16(
-	LPCOLESTR16 idstr,	/* [in] string representation of guid */
-	CLSID *id		/* [out] GUID converted from string */
-) {
-  BYTE *s = (BYTE *) idstr;
-  BYTE *p;
-  int	i;
-  BYTE table[256];
-
-  if (!s)
-	  s = "{00000000-0000-0000-0000-000000000000}";
-  else {  /* validate the CLSID string */
-
-      if (strlen(s) != 38)
-          return CO_E_CLASSSTRING;
-
-      if ((s[0]!='{') || (s[9]!='-') || (s[14]!='-') || (s[19]!='-') || (s[24]!='-') || (s[37]!='}'))
-          return CO_E_CLASSSTRING;
-
-      for (i=1; i<37; i++)
-      {
-          if ((i == 9)||(i == 14)||(i == 19)||(i == 24)) continue;
-          if (!(((s[i] >= '0') && (s[i] <= '9'))  ||
-                ((s[i] >= 'a') && (s[i] <= 'f'))  ||
-                ((s[i] >= 'A') && (s[i] <= 'F')))
-             )
-              return CO_E_CLASSSTRING;
-      }
-  }
-
-  TRACE("%s -> %p\n", s, id);
-
-  /* quick lookup table */
-  memset(table, 0, 256);
-
-  for (i = 0; i < 10; i++) {
-    table['0' + i] = i;
-  }
-  for (i = 0; i < 6; i++) {
-    table['A' + i] = i+10;
-    table['a' + i] = i+10;
-  }
-
-  /* in form {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} */
-
-  p = (BYTE *) id;
-
-  s++;	/* skip leading brace  */
-  for (i = 0; i < 4; i++) {
-    p[3 - i] = table[*s]<<4 | table[*(s+1)];
-    s += 2;
-  }
-  p += 4;
-  s++;	/* skip - */
-
-  for (i = 0; i < 2; i++) {
-    p[1-i] = table[*s]<<4 | table[*(s+1)];
-    s += 2;
-  }
-  p += 2;
-  s++;	/* skip - */
-
-  for (i = 0; i < 2; i++) {
-    p[1-i] = table[*s]<<4 | table[*(s+1)];
-    s += 2;
-  }
-  p += 2;
-  s++;	/* skip - */
-
-  /* these are just sequential bytes */
-  for (i = 0; i < 2; i++) {
-    *p++ = table[*s]<<4 | table[*(s+1)];
-    s += 2;
-  }
-  s++;	/* skip - */
-
-  for (i = 0; i < 6; i++) {
-    *p++ = table[*s]<<4 | table[*(s+1)];
-    s += 2;
-  }
-
-  return S_OK;
 }
 
@@ -553,4 +418,66 @@
  *	the converted GUID
  */
+HRESULT WINAPI __CLSIDFromStringA(
+	LPCSTR idstr,	        /* [in] string representation of guid */
+	CLSID *id)		/* [out] GUID converted from string */
+{
+  BYTE *s = (BYTE *) idstr;
+  int	i;
+  BYTE table[256];
+
+  if (!s)
+	  s = "{00000000-0000-0000-0000-000000000000}";
+  else {  /* validate the CLSID string */
+
+      if (strlen(s) != 38)
+          return CO_E_CLASSSTRING;
+
+      if ((s[0]!='{') || (s[9]!='-') || (s[14]!='-') || (s[19]!='-') || (s[24]!='-') || (s[37]!='}'))
+          return CO_E_CLASSSTRING;
+
+      for (i=1; i<37; i++) {
+          if ((i == 9)||(i == 14)||(i == 19)||(i == 24)) continue;
+          if (!(((s[i] >= '0') && (s[i] <= '9'))  ||
+                ((s[i] >= 'a') && (s[i] <= 'f'))  ||
+                ((s[i] >= 'A') && (s[i] <= 'F'))))
+              return CO_E_CLASSSTRING;
+      }
+  }
+
+  TRACE("%s -> %p\n", s, id);
+
+  /* quick lookup table */
+  memset(table, 0, 256);
+
+  for (i = 0; i < 10; i++) {
+    table['0' + i] = i;
+  }
+  for (i = 0; i < 6; i++) {
+    table['A' + i] = i+10;
+    table['a' + i] = i+10;
+  }
+
+  /* in form {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} */
+
+  id->Data1 = (table[s[1]] << 28 | table[s[2]] << 24 | table[s[3]] << 20 | table[s[4]] << 16 |
+               table[s[5]] << 12 | table[s[6]] << 8  | table[s[7]] << 4  | table[s[8]]);
+  id->Data2 = table[s[10]] << 12 | table[s[11]] << 8 | table[s[12]] << 4 | table[s[13]];
+  id->Data3 = table[s[15]] << 12 | table[s[16]] << 8 | table[s[17]] << 4 | table[s[18]];
+
+  /* these are just sequential bytes */
+  id->Data4[0] = table[s[20]] << 4 | table[s[21]];
+  id->Data4[1] = table[s[22]] << 4 | table[s[23]];
+  id->Data4[2] = table[s[25]] << 4 | table[s[26]];
+  id->Data4[3] = table[s[27]] << 4 | table[s[28]];
+  id->Data4[4] = table[s[29]] << 4 | table[s[30]];
+  id->Data4[5] = table[s[31]] << 4 | table[s[32]];
+  id->Data4[6] = table[s[33]] << 4 | table[s[34]];
+  id->Data4[7] = table[s[35]] << 4 | table[s[36]];
+
+  return S_OK;
+}
+
+/*****************************************************************************/
+
 HRESULT WINAPI CLSIDFromString(
 	LPCOLESTR idstr,	/* [in] string representation of GUID */
@@ -562,5 +489,7 @@
     if (!WideCharToMultiByte( CP_ACP, 0, idstr, -1, xid, sizeof(xid), NULL, NULL ))
         return CO_E_CLASSSTRING;
-    ret = CLSIDFromString16(xid,id);
+
+
+    ret = __CLSIDFromStringA(xid,id);
     if(ret != S_OK) { /* It appears a ProgID is also valid */
         ret = CLSIDFromProgID(idstr, id);
@@ -610,47 +539,6 @@
   return S_OK;
 }
-#ifndef __WIN32OS2__
-/******************************************************************************
- *		StringFromCLSID	[COMPOBJ.19]
- * Converts a GUID into the respective string representation.
- * The target string is allocated using the OLE IMalloc.
- * RETURNS
- *	the string representation and HRESULT
- */
-HRESULT WINAPI StringFromCLSID16(
-        REFCLSID id,            /* [in] the GUID to be converted */
-	LPOLESTR16 *idstr	/* [out] a pointer to a to-be-allocated segmented pointer pointing to the resulting string */
-
-) {
-    extern BOOL WINAPI K32WOWCallback16Ex( DWORD vpfn16, DWORD dwFlags,
-                                           DWORD cbArgs, LPVOID pArgs, LPDWORD pdwRetCode );
-    LPMALLOC16	mllc;
-    HRESULT	ret;
-    DWORD	args[2];
-
-    ret = CoGetMalloc16(0,&mllc);
-    if (ret) return ret;
-
-    args[0] = (DWORD)mllc;
-    args[1] = 40;
-
-    /* No need for a Callback entry, we have WOWCallback16Ex which does
-     * everything we need.
-     */
-    if (!K32WOWCallback16Ex(
-    	(DWORD)((ICOM_VTABLE(IMalloc16)*)MapSL(
-            (SEGPTR)ICOM_VTBL(((LPMALLOC16)MapSL((SEGPTR)mllc))))
-	)->Alloc,
-	WCB16_CDECL,
-	2*sizeof(DWORD),
-	(LPVOID)args,
-	(LPDWORD)idstr
-    )) {
-    	WARN("CallTo16 IMalloc16 failed\n");
-    	return E_FAIL;
-    }
-    return WINE_StringFromCLSID(id,MapSL((SEGPTR)*idstr));
-}
-#endif
+
+
 /******************************************************************************
  *		StringFromCLSID	[OLE32.151]
@@ -755,35 +643,4 @@
 
 /******************************************************************************
- *		CLSIDFromProgID	[COMPOBJ.61]
- * Converts a program id into the respective GUID. (By using a registry lookup)
- * RETURNS
- *	riid associated with the progid
- */
-HRESULT WINAPI CLSIDFromProgID16(
-	LPCOLESTR16 progid,	/* [in] program id as found in registry */
-	LPCLSID riid		/* [out] associated CLSID */
-) {
-	char	*buf,buf2[80];
-	DWORD	buf2len;
-	HRESULT	err;
-	HKEY	xhkey;
-
-	buf = HeapAlloc(GetProcessHeap(),0,strlen(progid)+8);
-	sprintf(buf,"%s\\CLSID",progid);
-	if ((err=RegOpenKeyA(HKEY_CLASSES_ROOT,buf,&xhkey))) {
-		HeapFree(GetProcessHeap(),0,buf);
-                return CO_E_CLASSSTRING;
-	}
-	HeapFree(GetProcessHeap(),0,buf);
-	buf2len = sizeof(buf2);
-	if ((err=RegQueryValueA(xhkey,NULL,buf2,&buf2len))) {
-		RegCloseKey(xhkey);
-                return CO_E_CLASSSTRING;
-	}
-	RegCloseKey(xhkey);
-	return CLSIDFromString16(buf2,riid);
-}
-
-/******************************************************************************
  *		CLSIDFromProgID	[OLE32.2]
  * Converts a program id into the respective GUID. (By using a registry lookup)
@@ -816,5 +673,5 @@
     }
     RegCloseKey(xhkey);
-    return CLSIDFromString16(buf2,riid);
+    return __CLSIDFromStringA(buf2,riid);
 }
 
@@ -877,6 +734,5 @@
     /* We have the CLSid we want back from the registry as a string, so
        lets convert it into a CLSID structure */
-    if ( (CLSIDFromString16(buf2,pclsid)) != NOERROR)
-    {
+    if ( (__CLSIDFromStringA(buf2,pclsid)) != NOERROR) {
        return E_INVALIDARG;
     }
@@ -928,85 +784,6 @@
         return S_OK;
 }
-#ifndef __WIN32OS2__
-/* FIXME: this function is not declared in the WINELIB headers. But where should it go ? */
-/***********************************************************************
- *           LookupETask (COMPOBJ.94)
- */
-HRESULT WINAPI LookupETask16(HTASK16 *hTask,LPVOID p) {
-	FIXME("(%p,%p),stub!\n",hTask,p);
-	if ((*hTask = GetCurrentTask()) == hETask) {
-		memcpy(p, Table_ETask, sizeof(Table_ETask));
-	}
-	return 0;
-}
-
-/* FIXME: this function is not declared in the WINELIB headers. But where should it go ? */
-/***********************************************************************
- *           SetETask (COMPOBJ.95)
- */
-HRESULT WINAPI SetETask16(HTASK16 hTask, LPVOID p) {
-        FIXME("(%04x,%p),stub!\n",hTask,p);
-	hETask = hTask;
-	return 0;
-}
-
-/* FIXME: this function is not declared in the WINELIB headers. But where should it go ? */
-/***********************************************************************
- *           CALLOBJECTINWOW (COMPOBJ.201)
- */
-HRESULT WINAPI CallObjectInWOW(LPVOID p1,LPVOID p2) {
-	FIXME("(%p,%p),stub!\n",p1,p2);
-	return 0;
-}
-
-/******************************************************************************
- *		CoRegisterClassObject	[COMPOBJ.5]
- *
- * Don't know where it registers it ...
- */
-HRESULT WINAPI CoRegisterClassObject16(
-	REFCLSID rclsid,
-	LPUNKNOWN pUnk,
-	DWORD dwClsContext, /* [in] CLSCTX flags indicating the context in which to run the executable */
-	DWORD flags,        /* [in] REGCLS flags indicating how connections are made */
-	LPDWORD lpdwRegister
-) {
-	char	buf[80];
-
-	WINE_StringFromCLSID(rclsid,buf);
-
-	FIXME("(%s,%p,0x%08lx,0x%08lx,%p),stub\n",
-		buf,pUnk,dwClsContext,flags,lpdwRegister
-	);
-	return 0;
-}
-
-
-/******************************************************************************
- *      CoRevokeClassObject [COMPOBJ.6]
- *
- */
-HRESULT WINAPI CoRevokeClassObject16(DWORD dwRegister) /* [in] token on class obj */
-{
-    FIXME("(0x%08lx),stub!\n", dwRegister);
-    return 0;
-}
-
-/******************************************************************************
- *      CoFileTimeToDosDateTime [COMPOBJ.30]
- */
-BOOL16 WINAPI CoFileTimeToDosDateTime16(const FILETIME *ft, LPWORD lpDosDate, LPWORD lpDosTime)
-{
-    return FileTimeToDosDateTime(ft, lpDosDate, lpDosTime);
-}
-
-/******************************************************************************
- *      CoDosDateTimeToFileTime [COMPOBJ.31]
- */
-BOOL16 WINAPI CoDosDateTimeToFileTime16(WORD wDosDate, WORD wDosTime, FILETIME *ft)
-{
-    return DosDateTimeToFileTime(wDosDate, wDosTime, ft);
-}
-#endif
+
+
 /***
  * COM_GetRegisteredClassObject
@@ -1296,4 +1073,30 @@
 
 /***********************************************************************
+ *	compobj_RegReadPath	[internal]
+ *
+ *	Reads a registry value and expands it when nessesary
+ */
+HRESULT compobj_RegReadPath(char * keyname, char * valuename, char * dst, int dstlen)
+{
+	HRESULT hres;
+	HKEY key;
+	DWORD keytype;
+	char src[MAX_PATH];
+	DWORD dwLength = dstlen;
+
+	if((hres = RegOpenKeyExA(HKEY_CLASSES_ROOT, keyname, 0, KEY_READ, &key)) == ERROR_SUCCESS) {
+          if( (hres = RegQueryValueExA(key, NULL, NULL, &keytype, (LPBYTE)src, &dwLength)) == ERROR_SUCCESS ) {
+            if (keytype == REG_EXPAND_SZ) {
+              if (dstlen <= ExpandEnvironmentStringsA(src, dst, dstlen)) hres = ERROR_MORE_DATA;
+            } else {
+              strncpy(dst, src, dstlen);
+            }
+	  }
+          RegCloseKey (key);
+	}
+	return hres;
+}
+
+/***********************************************************************
  *           CoGetClassObject [COMPOBJ.7]
  *           CoGetClassObject [OLE32.16]
@@ -1311,13 +1114,9 @@
     HRESULT	hres = E_UNEXPECTED;
     char	xclsid[80];
-    WCHAR ProviderName[MAX_PATH+1];
-    DWORD ProviderNameLen = sizeof(ProviderName);
     HINSTANCE hLibrary;
 #ifdef __WIN32OS2__
-    typedef HRESULT (* CALLBACK DllGetClassObjectFunc)(REFCLSID clsid,
-			     REFIID iid, LPVOID *ppv);
+    typedef HRESULT (* CALLBACK DllGetClassObjectFunc)(REFCLSID clsid, REFIID iid, LPVOID *ppv);
 #else
-    typedef HRESULT (CALLBACK *DllGetClassObjectFunc)(REFCLSID clsid,
-			     REFIID iid, LPVOID *ppv);
+    typedef HRESULT (CALLBACK *DllGetClassObjectFunc)(REFCLSID clsid, REFIID iid, LPVOID *ppv);
 #endif
     DllGetClassObjectFunc DllGetClassObject;
@@ -1325,8 +1124,5 @@
     WINE_StringFromCLSID((LPCLSID)rclsid,xclsid);
 
-    TRACE("\n\tCLSID:\t%s,\n\tIID:\t%s\n",
-	debugstr_guid(rclsid),
-	debugstr_guid(iid)
-    );
+    TRACE("\n\tCLSID:\t%s,\n\tIID:\t%s\n", debugstr_guid(rclsid), debugstr_guid(iid));
 
     if (pServerInfo) {
@@ -1356,38 +1152,32 @@
     }
 
-    if ((CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER) & dwClsContext) {
-        HKEY key;
-	char buf[200];
-
-	memset(ProviderName,0,sizeof(ProviderName));
-	sprintf(buf,"CLSID\\%s\\InprocServer32",xclsid);
-        if (((hres = RegOpenKeyExA(HKEY_CLASSES_ROOT, buf, 0, KEY_READ, &key)) != ERROR_SUCCESS) ||
-            ((hres = RegQueryValueExW(key,NULL,NULL,NULL,(LPBYTE)ProviderName,&ProviderNameLen)),
-             RegCloseKey (key),
-             hres != ERROR_SUCCESS))
-        {
+    /* first try: in-process */
+    if ((CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER) & dwClsContext) {
+	char keyname[MAX_PATH];
+	char dllpath[MAX_PATH+1];
+
+	sprintf(keyname,"CLSID\\%s\\InprocServer32",xclsid);
+
+	if ( compobj_RegReadPath(keyname, NULL, dllpath, sizeof(dllpath)) != ERROR_SUCCESS) {
+	    /* failure: CLSID is not found in registry */
+	    WARN("class %s not registred\n", xclsid);
             hres = REGDB_E_CLASSNOTREG;
-        }
-        /* Don't ask me.  MSDN says that CoGetClassObject does NOT call CoLoadLibrary */
-        else if ((hLibrary = CoLoadLibrary(ProviderName, TRUE)) == 0)
-        {
-	    FIXME("couldn't load InprocServer32 dll %s\n", debugstr_w(ProviderName));
-	    hres = E_ACCESSDENIED; /* or should this be CO_E_DLLNOTFOUND? */
+	} else {
+	  if ((hLibrary = LoadLibraryExA(dllpath, 0, LOAD_WITH_ALTERED_SEARCH_PATH)) == 0) {
+	    /* failure: DLL could not be loaded */
+	    ERR("couldn't load InprocServer32 dll %s\n", dllpath);
+	    hres = E_ACCESSDENIED; /* FIXME: or should this be CO_E_DLLNOTFOUND? */
+	  } else if (!(DllGetClassObject = (DllGetClassObjectFunc)GetProcAddress(hLibrary, "DllGetClassObject"))) {
+	    /* failure: the dll did not export DllGetClassObject */
+	    ERR("couldn't find function DllGetClassObject in %s\n", dllpath);
+	    FreeLibrary( hLibrary );
+	    hres = CO_E_DLLNOTFOUND;
+	  } else {
+	    /* OK: get the ClassObject */
+	    COMPOBJ_DLLList_Add( hLibrary );
+	    return DllGetClassObject(rclsid, iid, ppv);
+	  }
 	}
-	else if (!(DllGetClassObject = (DllGetClassObjectFunc)GetProcAddress(hLibrary, "DllGetClassObject")))
-        {
-	    /* not sure if this should be called here CoFreeLibrary(hLibrary);*/
-	    FIXME("couldn't find function DllGetClassObject in %s\n", debugstr_w(ProviderName));
-	    hres = E_ACCESSDENIED;
-	}
-        else
-        {
-	    /* Ask the DLL for its class object. (there was a note here about
-	     * class factories but this is good.
-	     */
-	    return DllGetClassObject(rclsid, iid, ppv);
-        }
-    }
-
+    }
 
     /* Next try out of process */
@@ -1426,10 +1216,12 @@
     IStorage *pstg=0;
     HRESULT res;
-    int nbElm=0,length=0,i=0;
-    LONG sizeProgId=20;
+    int nbElm, length, i;
+    LONG sizeProgId;
     LPOLESTR *pathDec=0,absFile=0,progId=0;
-    WCHAR extention[100]={0};
-
-    TRACE("()\n");
+    LPWSTR extension;
+    static const WCHAR bkslashW[] = {'\\',0};
+    static const WCHAR dotW[] = {'.',0};
+
+    TRACE("%s, %p\n", debugstr_w(filePathName), pclsid);
 
     /* if the file contain a storage object the return the CLSID writen by IStorage_SetClass method*/
@@ -1475,21 +1267,22 @@
 
     /* failed if the path represente a directory and not an absolute file name*/
-    if (lstrcmpW(absFile,(LPOLESTR)"\\"))
+    if (!lstrcmpW(absFile, bkslashW))
         return MK_E_INVALIDEXTENSION;
 
     /* get the extension of the file */
+    extension = NULL;
     length=lstrlenW(absFile);
-    for(i=length-1; ( (i>=0) && (extention[i]=absFile[i]) );i--);
+    for(i = length-1; (i >= 0) && *(extension = &absFile[i]) != '.'; i--)
+        /* nothing */;
+
+    if (!extension || !lstrcmpW(extension, dotW))
+        return MK_E_INVALIDEXTENSION;
+
+    res=RegQueryValueW(HKEY_CLASSES_ROOT, extension, NULL, &sizeProgId);
 
     /* get the progId associated to the extension */
-    progId=CoTaskMemAlloc(sizeProgId);
-
-    res=RegQueryValueW(HKEY_CLASSES_ROOT,extention,progId,&sizeProgId);
-
-    if (res==ERROR_MORE_DATA){
-
-        progId = CoTaskMemRealloc(progId,sizeProgId);
-        res=RegQueryValueW(HKEY_CLASSES_ROOT,extention,progId,&sizeProgId);
-    }
+    progId = CoTaskMemAlloc(sizeProgId);
+    res = RegQueryValueW(HKEY_CLASSES_ROOT, extension, progId, &sizeProgId);
+
     if (res==ERROR_SUCCESS)
         /* return the clsid associated to the progId */
@@ -1507,15 +1300,4 @@
     return MK_E_INVALIDEXTENSION;
 }
-/******************************************************************************
- *		CoRegisterMessageFilter	[COMPOBJ.27]
- */
-HRESULT WINAPI CoRegisterMessageFilter16(
-	LPMESSAGEFILTER lpMessageFilter,
-	LPMESSAGEFILTER *lplpMessageFilter
-) {
-	FIXME("(%p,%p),stub!\n",lpMessageFilter,lplpMessageFilter);
-	return 0;
-}
-
 /***********************************************************************
  *           CoCreateInstance [COMPOBJ.13]
@@ -1644,41 +1426,21 @@
 
 /***********************************************************************
+ *           CoLoadLibrary (OLE32.30)
+ */
+HINSTANCE WINAPI CoLoadLibrary(LPOLESTR lpszLibName, BOOL bAutoFree)
+{
+    TRACE("(%s, %d)\n", debugstr_w(lpszLibName), bAutoFree);
+
+    return LoadLibraryExW(lpszLibName, 0, LOAD_WITH_ALTERED_SEARCH_PATH);
+}
+
+/***********************************************************************
  *           CoFreeLibrary [OLE32.13]
+ *
+ * NOTES: don't belive the docu
  */
 void WINAPI CoFreeLibrary(HINSTANCE hLibrary)
 {
-    OpenDll *ptr, *prev;
-    OpenDll *tmp;
-
-    EnterCriticalSection( &csOpenDllList );
-
-    /* lookup library in linked list */
-    prev = NULL;
-    for (ptr = openDllList; ptr != NULL; ptr=ptr->next) {
-	if (ptr->hLibrary == hLibrary) {
-	    break;
-	}
-	prev = ptr;
-    }
-
-    if (ptr == NULL) {
-	/* shouldn't happen if user passed in a valid hLibrary */
-	goto end;
-    }
-    /* assert: ptr points to the library entry to free */
-
-    /* free library and remove node from list */
-    FreeLibrary(hLibrary);
-    if (ptr == openDllList) {
-	tmp = openDllList->next;
-	HeapFree(GetProcessHeap(), 0, openDllList);
-	openDllList = tmp;
-    } else {
-	tmp = ptr->next;
-	HeapFree(GetProcessHeap(), 0, ptr);
-	prev->next = tmp;
-    }
-end:
-    LeaveCriticalSection( &csOpenDllList );
+	FreeLibrary(hLibrary);
 }
 
@@ -1686,20 +1448,11 @@
 /***********************************************************************
  *           CoFreeAllLibraries [OLE32.12]
+ *
+ * NOTES: don't belive the docu
  */
 void WINAPI CoFreeAllLibraries(void)
 {
-    OpenDll *ptr, *tmp;
-
-    EnterCriticalSection( &csOpenDllList );
-
-    for (ptr = openDllList; ptr != NULL; ) {
-	tmp=ptr->next;
-	CoFreeLibrary(ptr->hLibrary);
-	ptr = tmp;
-    }
-
-    LeaveCriticalSection( &csOpenDllList );
-}
-
+        /* NOP */
+}
 
 
@@ -1707,28 +1460,11 @@
  *           CoFreeUnusedLibraries [COMPOBJ.17]
  *           CoFreeUnusedLibraries [OLE32.14]
+ *
+ * FIXME: Calls to CoFreeUnusedLibraries from any thread always route
+ * through the main apartment's thread to call DllCanUnloadNow
  */
 void WINAPI CoFreeUnusedLibraries(void)
 {
-    OpenDll *ptr, *tmp;
-    typedef HRESULT(*DllCanUnloadNowFunc)(void);
-    DllCanUnloadNowFunc DllCanUnloadNow;
-
-    EnterCriticalSection( &csOpenDllList );
-
-    for (ptr = openDllList; ptr != NULL; ) {
-	DllCanUnloadNow = (DllCanUnloadNowFunc)
-	    GetProcAddress(ptr->hLibrary, "DllCanUnloadNow");
-
-	if ( (DllCanUnloadNow != NULL) &&
-	     (DllCanUnloadNow() == S_OK) ) {
-	    tmp=ptr->next;
-	    CoFreeLibrary(ptr->hLibrary);
-	    ptr = tmp;
-	} else {
-	    ptr=ptr->next;
-	}
-    }
-
-    LeaveCriticalSection( &csOpenDllList );
+    COMPOBJ_DllList_FreeUnused(0);
 }
 
@@ -1747,116 +1483,219 @@
 
 /***********************************************************************
- *           CoTaskMemAlloc (OLE32.43)
- * RETURNS
- * 	pointer to newly allocated block
- */
-LPVOID WINAPI CoTaskMemAlloc(
-	ULONG size	/* [in] size of memoryblock to be allocated */
-) {
-    LPMALLOC	lpmalloc;
-    HRESULT	ret = CoGetMalloc(0,&lpmalloc);
-
-    if (FAILED(ret))
-	return NULL;
-
-    return IMalloc_Alloc(lpmalloc,size);
-}
-/***********************************************************************
- *           CoTaskMemFree (OLE32.44)
- */
-VOID WINAPI CoTaskMemFree(
-	LPVOID ptr	/* [in] pointer to be freed */
-) {
-    LPMALLOC	lpmalloc;
-    HRESULT	ret = CoGetMalloc(0,&lpmalloc);
-
-    if (FAILED(ret))
-      return;
-
-    IMalloc_Free(lpmalloc, ptr);
-}
-
-/***********************************************************************
- *           CoTaskMemRealloc (OLE32.45)
- * RETURNS
- * 	pointer to newly allocated block
- */
-LPVOID WINAPI CoTaskMemRealloc(
-  LPVOID pvOld,
-  ULONG  size)	/* [in] size of memoryblock to be allocated */
-{
-  LPMALLOC lpmalloc;
-  HRESULT  ret = CoGetMalloc(0,&lpmalloc);
-
-  if (FAILED(ret))
-    return NULL;
-
-  return IMalloc_Realloc(lpmalloc, pvOld, size);
-}
-
-/***********************************************************************
  *           CoLoadLibrary (OLE32.30)
  */
-HINSTANCE WINAPI CoLoadLibrary(LPOLESTR lpszLibName, BOOL bAutoFree)
-{
-    HINSTANCE hLibrary;
-    OpenDll *ptr;
-    OpenDll *tmp;
-
-    TRACE("(%s, %d)\n", debugstr_w(lpszLibName), bAutoFree);
-
-    hLibrary = LoadLibraryExW(lpszLibName, 0, LOAD_WITH_ALTERED_SEARCH_PATH);
-
-    if (!bAutoFree)
-	return hLibrary;
-
-    EnterCriticalSection( &csOpenDllList );
-
-    if (openDllList == NULL) {
-        /* empty list -- add first node */
-        openDllList = (OpenDll*)HeapAlloc(GetProcessHeap(),0, sizeof(OpenDll));
-	openDllList->hLibrary=hLibrary;
-	openDllList->next = NULL;
+static void COM_RevokeAllClasses()
+{
+  EnterCriticalSection( &csRegisteredClassList );
+
+  while (firstRegisteredClass!=0)
+  {
+    CoRevokeClassObject(firstRegisteredClass->dwCookie);
+  }
+
+  LeaveCriticalSection( &csRegisteredClassList );
+}
+
+/****************************************************************************
+ *  COM External Lock methods implementation
+ *
+ *  This api provides a linked list to managed external references to
+ *  COM objects.
+ *
+ *  The public interface consists of three calls:
+ *      COM_ExternalLockAddRef
+ *      COM_ExternalLockRelease
+ *      COM_ExternalLockFreeList
+ */
+
+#define EL_END_OF_LIST 0
+#define EL_NOT_FOUND   0
+
+/*
+ * Declaration of the static structure that manage the
+ * external lock to COM  objects.
+ */
+typedef struct COM_ExternalLock     COM_ExternalLock;
+typedef struct COM_ExternalLockList COM_ExternalLockList;
+
+struct COM_ExternalLock
+{
+  IUnknown         *pUnk;     /* IUnknown referenced */
+  ULONG            uRefCount; /* external lock counter to IUnknown object*/
+  COM_ExternalLock *next;     /* Pointer to next element in list */
+};
+
+struct COM_ExternalLockList
+{
+  COM_ExternalLock *head;     /* head of list */
+};
+
+/*
+ * Declaration and initialization of the static structure that manages
+ * the external lock to COM objects.
+ */
+static COM_ExternalLockList elList = { EL_END_OF_LIST };
+
+/*
+ * Private methods used to managed the linked list
+ */
+
+
+static COM_ExternalLock* COM_ExternalLockLocate(
+  COM_ExternalLock *element,
+  IUnknown         *pUnk);
+
+/****************************************************************************
+ * Internal - Insert a new IUnknown* to the linked list
+ */
+static BOOL COM_ExternalLockInsert(
+  IUnknown *pUnk)
+{
+  COM_ExternalLock *newLock      = NULL;
+  COM_ExternalLock *previousHead = NULL;
+
+  /*
+   * Allocate space for the new storage object
+   */
+  newLock = HeapAlloc(GetProcessHeap(), 0, sizeof(COM_ExternalLock));
+
+  if (newLock!=NULL) {
+    if ( elList.head == EL_END_OF_LIST ) {
+      elList.head = newLock;    /* The list is empty */
     } else {
-        /* search for this dll */
-        int found = FALSE;
-        for (ptr = openDllList; ptr->next != NULL; ptr=ptr->next) {
-  	    if (ptr->hLibrary == hLibrary) {
-	        found = TRUE;
-		break;
-	    }
-        }
-	if (!found) {
-	    /* dll not found, add it */
- 	    tmp = openDllList;
-	    openDllList = (OpenDll*)HeapAlloc(GetProcessHeap(),0, sizeof(OpenDll));
-	    openDllList->hLibrary = hLibrary;
-	    openDllList->next = tmp;
-	}
-    }
-
-    LeaveCriticalSection( &csOpenDllList );
-
-    return hLibrary;
-}
-
-/***********************************************************************
- *           CoInitializeWOW (OLE32.27)
- */
-HRESULT WINAPI CoInitializeWOW(DWORD x,DWORD y) {
-    FIXME("(0x%08lx,0x%08lx),stub!\n",x,y);
-    return 0;
-}
-
-/******************************************************************************
- *		CoLockObjectExternal	[COMPOBJ.63]
- */
-HRESULT WINAPI CoLockObjectExternal16(
-    LPUNKNOWN pUnk,		/* [in] object to be locked */
-    BOOL16 fLock,		/* [in] do lock */
-    BOOL16 fLastUnlockReleases	/* [in] ? */
-) {
-    FIXME("(%p,%d,%d),stub!\n",pUnk,fLock,fLastUnlockReleases);
-    return S_OK;
+      /* insert does it at the head */
+      previousHead  = elList.head;
+      elList.head = newLock;
+    }
+
+    /* Set new list item data member */
+    newLock->pUnk      = pUnk;
+    newLock->uRefCount = 1;
+    newLock->next      = previousHead;
+
+    return TRUE;
+  }
+  return FALSE;
+}
+
+/****************************************************************************
+ * Internal - Method that removes an item from the linked list.
+ */
+static void COM_ExternalLockDelete(
+  COM_ExternalLock *itemList)
+{
+  COM_ExternalLock *current = elList.head;
+
+  if ( current == itemList ) {
+    /* this section handles the deletion of the first node */
+    elList.head = itemList->next;
+    HeapFree( GetProcessHeap(), 0, itemList);
+  } else {
+    do {
+      if ( current->next == itemList ){   /* We found the item to free  */
+        current->next = itemList->next;  /* readjust the list pointers */
+        HeapFree( GetProcessHeap(), 0, itemList);
+        break;
+      }
+
+      /* Skip to the next item */
+      current = current->next;
+
+    } while ( current != EL_END_OF_LIST );
+  }
+}
+
+/****************************************************************************
+ * Internal - Recursivity agent for IUnknownExternalLockList_Find
+ *
+ * NOTES: how long can the list be ?? (recursive!!!)
+ */
+static COM_ExternalLock* COM_ExternalLockLocate( COM_ExternalLock *element, IUnknown *pUnk)
+{
+  if ( element == EL_END_OF_LIST )
+    return EL_NOT_FOUND;
+  else if ( element->pUnk == pUnk )    /* We found it */
+    return element;
+  else                                 /* Not the right guy, keep on looking */
+    return COM_ExternalLockLocate( element->next, pUnk);
+}
+
+/****************************************************************************
+ * Public - Method that increments the count for a IUnknown* in the linked
+ * list.  The item is inserted if not already in the list.
+ */
+static void COM_ExternalLockAddRef(IUnknown *pUnk)
+{
+  COM_ExternalLock *externalLock = COM_ExternalLockLocate(elList.head, pUnk);
+
+  /*
+   * Add an external lock to the object. If it was already externally
+   * locked, just increase the reference count. If it was not.
+   * add the item to the list.
+   */
+  if ( externalLock == EL_NOT_FOUND )
+    COM_ExternalLockInsert(pUnk);
+  else
+    externalLock->uRefCount++;
+
+  /*
+   * Add an internal lock to the object
+   */
+  IUnknown_AddRef(pUnk);
+}
+
+/****************************************************************************
+ * Public - Method that decrements the count for a IUnknown* in the linked
+ * list.  The item is removed from the list if its count end up at zero or if
+ * bRelAll is TRUE.
+ */
+static void COM_ExternalLockRelease(
+  IUnknown *pUnk,
+  BOOL   bRelAll)
+{
+  COM_ExternalLock *externalLock = COM_ExternalLockLocate(elList.head, pUnk);
+
+  if ( externalLock != EL_NOT_FOUND ) {
+    do {
+      externalLock->uRefCount--;  /* release external locks      */
+      IUnknown_Release(pUnk);     /* release local locks as well */
+
+      if ( bRelAll == FALSE ) break;  /* perform single release */
+
+    } while ( externalLock->uRefCount > 0 );
+
+    if ( externalLock->uRefCount == 0 )  /* get rid of the list entry */
+      COM_ExternalLockDelete(externalLock);
+  }
+}
+/****************************************************************************
+ * Public - Method that frees the content of the list.
+ */
+static void COM_ExternalLockFreeList()
+{
+  COM_ExternalLock *head;
+
+  head = elList.head;                 /* grab it by the head             */
+  while ( head != EL_END_OF_LIST ) {
+    COM_ExternalLockDelete(head);     /* get rid of the head stuff       */
+    head = elList.head;               /* get the new head...             */
+  }
+}
+
+/****************************************************************************
+ * Public - Method that dump the content of the list.
+ */
+void COM_ExternalLockDump()
+{
+  COM_ExternalLock *current = elList.head;
+
+  DPRINTF("\nExternal lock list contains:\n");
+
+  while ( current != EL_END_OF_LIST ) {
+    DPRINTF( "\t%p with %lu references count.\n", current->pUnk, current->uRefCount);
+
+    /* Skip to the next item */
+    current = current->next;
+  }
 }
 
@@ -1870,289 +1709,78 @@
 {
 
-  if (fLock)
-  {
-    /*
-     * Increment the external lock coutner, COM_ExternalLockAddRef also
-     * increment the object's internal lock counter.
-     */
-    COM_ExternalLockAddRef( pUnk);
-  }
-  else
-  {
-    /*
-     * Decrement the external lock coutner, COM_ExternalLockRelease also
-     * decrement the object's internal lock counter.
-     */
-    COM_ExternalLockRelease( pUnk, fLastUnlockReleases);
-  }
-
-    return S_OK;
-}
-
-/***********************************************************************
- *           CoGetState [COMPOBJ.115]
- */
-HRESULT WINAPI CoGetState16(LPDWORD state)
-{
-    FIXME("(%p),stub!\n", state);
-    *state = 0;
-    return S_OK;
-}
+	if (fLock) {
+            /*
+             * Increment the external lock coutner, COM_ExternalLockAddRef also
+             * increment the object's internal lock counter.
+             */
+	    COM_ExternalLockAddRef( pUnk);
+        } else {
+            /*
+             * Decrement the external lock coutner, COM_ExternalLockRelease also
+             * decrement the object's internal lock counter.
+             */
+            COM_ExternalLockRelease( pUnk, fLastUnlockReleases);
+        }
+
+        return S_OK;
+}
+
+/***********************************************************************
+ *           CoInitializeWOW (OLE32.27)
+ */
+HRESULT WINAPI CoInitializeWOW(DWORD x,DWORD y) {
+    FIXME("(0x%08lx,0x%08lx),stub!\n",x,y);
+    return 0;
+}
+
+static IUnknown * pUnkState = 0; /* FIXME: thread local */
+static int nStatCounter = 0;	 /* global */
+static HMODULE hOleAut32 = 0;	 /* global */
+
+/***********************************************************************
+ *           CoGetState [OLE32.24]
+ *
+ * NOTES: might be incomplete
+ */
+HRESULT WINAPI CoGetState(IUnknown ** ppv)
+{
+	FIXME("\n");
+
+	if(pUnkState) {
+	    IUnknown_AddRef(pUnkState);
+	    *ppv = pUnkState;
+	    FIXME("-- %p\n", *ppv);
+	    return S_OK;
+	}
+	*ppv = NULL;
+	return E_FAIL;
+
+}
+
 /***********************************************************************
  *           CoSetState [OLE32.42]
- */
-HRESULT WINAPI CoSetState(LPDWORD state)
-{
-    FIXME("(%p),stub!\n", state);
-    if (state) *state = 0;
-    return S_OK;
-}
-/***********************************************************************
- *          CoCreateFreeThreadedMarshaler [OLE32.5]
- */
-HRESULT WINAPI CoCreateFreeThreadedMarshaler (LPUNKNOWN punkOuter, LPUNKNOWN* ppunkMarshal)
-{
-   FIXME ("(%p %p): stub\n", punkOuter, ppunkMarshal);
-
-   return S_OK;
-}
-
-/***
- * COM_RevokeAllClasses
- *
- * This method is called when the COM libraries are uninitialized to
- * release all the references to the class objects registered with
- * the library
- */
-static void COM_RevokeAllClasses()
-{
-  EnterCriticalSection( &csRegisteredClassList );
-
-  while (firstRegisteredClass!=0)
-  {
-    CoRevokeClassObject(firstRegisteredClass->dwCookie);
-  }
-
-  LeaveCriticalSection( &csRegisteredClassList );
-}
-
-/****************************************************************************
- *  COM External Lock methods implementation
- */
-
-/****************************************************************************
- * Public - Method that increments the count for a IUnknown* in the linked
- * list.  The item is inserted if not already in the list.
- */
-static void COM_ExternalLockAddRef(
-  IUnknown *pUnk)
-{
-  COM_ExternalLock *externalLock = COM_ExternalLockFind(pUnk);
-
-  /*
-   * Add an external lock to the object. If it was already externally
-   * locked, just increase the reference count. If it was not.
-   * add the item to the list.
-   */
-  if ( externalLock == EL_NOT_FOUND )
-    COM_ExternalLockInsert(pUnk);
-  else
-    externalLock->uRefCount++;
-
-  /*
-   * Add an internal lock to the object
-   */
-  IUnknown_AddRef(pUnk);
-}
-
-/****************************************************************************
- * Public - Method that decrements the count for a IUnknown* in the linked
- * list.  The item is removed from the list if its count end up at zero or if
- * bRelAll is TRUE.
- */
-static void COM_ExternalLockRelease(
-  IUnknown *pUnk,
-  BOOL   bRelAll)
-{
-  COM_ExternalLock *externalLock = COM_ExternalLockFind(pUnk);
-
-  if ( externalLock != EL_NOT_FOUND )
-  {
-    do
-    {
-      externalLock->uRefCount--;  /* release external locks      */
-      IUnknown_Release(pUnk);     /* release local locks as well */
-
-      if ( bRelAll == FALSE )
-        break;  /* perform single release */
-
-    } while ( externalLock->uRefCount > 0 );
-
-    if ( externalLock->uRefCount == 0 )  /* get rid of the list entry */
-      COM_ExternalLockDelete(externalLock);
-  }
-}
-/****************************************************************************
- * Public - Method that frees the content of the list.
- */
-static void COM_ExternalLockFreeList()
-{
-  COM_ExternalLock *head;
-
-  head = elList.head;                 /* grab it by the head             */
-  while ( head != EL_END_OF_LIST )
-  {
-    COM_ExternalLockDelete(head);     /* get rid of the head stuff       */
-
-    head = elList.head;               /* get the new head...             */
-  }
-}
-
-/****************************************************************************
- * Public - Method that dump the content of the list.
- */
-void COM_ExternalLockDump()
-{
-  COM_ExternalLock *current = elList.head;
-
-  DPRINTF("\nExternal lock list contains:\n");
-
-  while ( current != EL_END_OF_LIST )
-  {
-      DPRINTF( "\t%p with %lu references count.\n", current->pUnk, current->uRefCount);
-
-    /* Skip to the next item */
-    current = current->next;
-  }
-
-}
-
-/****************************************************************************
- * Internal - Find a IUnknown* in the linked list
- */
-static COM_ExternalLock* COM_ExternalLockFind(
-  IUnknown *pUnk)
-{
-  return COM_ExternalLockLocate(elList.head, pUnk);
-}
-
-/****************************************************************************
- * Internal - Recursivity agent for IUnknownExternalLockList_Find
- */
-static COM_ExternalLock* COM_ExternalLockLocate(
-  COM_ExternalLock *element,
-  IUnknown         *pUnk)
-{
-  if ( element == EL_END_OF_LIST )
-    return EL_NOT_FOUND;
-
-  else if ( element->pUnk == pUnk )    /* We found it */
-    return element;
-
-  else                                 /* Not the right guy, keep on looking */
-    return COM_ExternalLockLocate( element->next, pUnk);
-}
-
-/****************************************************************************
- * Internal - Insert a new IUnknown* to the linked list
- */
-static BOOL COM_ExternalLockInsert(
-  IUnknown *pUnk)
-{
-  COM_ExternalLock *newLock      = NULL;
-  COM_ExternalLock *previousHead = NULL;
-
-  /*
-   * Allocate space for the new storage object
-   */
-  newLock = HeapAlloc(GetProcessHeap(), 0, sizeof(COM_ExternalLock));
-
-  if (newLock!=NULL)
-  {
-    if ( elList.head == EL_END_OF_LIST )
-    {
-      elList.head = newLock;    /* The list is empty */
-    }
-    else
-    {
-      /*
-       * insert does it at the head
-       */
-      previousHead  = elList.head;
-      elList.head = newLock;
-    }
-
-    /*
-     * Set new list item data member
-     */
-    newLock->pUnk      = pUnk;
-    newLock->uRefCount = 1;
-    newLock->next      = previousHead;
-
-    return TRUE;
-  }
-  else
-    return FALSE;
-}
-
-/****************************************************************************
- * Internal - Method that removes an item from the linked list.
- */
-static void COM_ExternalLockDelete(
-  COM_ExternalLock *itemList)
-{
-  COM_ExternalLock *current = elList.head;
-
-  if ( current == itemList )
-  {
-    /*
-     * this section handles the deletion of the first node
-     */
-    elList.head = itemList->next;
-    HeapFree( GetProcessHeap(), 0, itemList);
-  }
-  else
-  {
-    do
-    {
-      if ( current->next == itemList )   /* We found the item to free  */
-      {
-        current->next = itemList->next;  /* readjust the list pointers */
-
-        HeapFree( GetProcessHeap(), 0, itemList);
-        break;
-      }
-
-      /* Skip to the next item */
-      current = current->next;
-
-    } while ( current != EL_END_OF_LIST );
-  }
-}
-
-/***********************************************************************
- *      DllEntryPoint                   [COMPOBJ.116]
- *
- *    Initialization code for the COMPOBJ DLL
- *
- * RETURNS:
- */
-BOOL WINAPI COMPOBJ_DllEntryPoint(DWORD Reason, HINSTANCE16 hInst, WORD ds, WORD HeapSize, DWORD res1, WORD res2)
-{
-        TRACE("(%08lx, %04x, %04x, %04x, %08lx, %04x)\n", Reason, hInst, ds, HeapSize,
- res1, res2);
-        switch(Reason)
-        {
-        case DLL_PROCESS_ATTACH:
-                if (!COMPOBJ_Attach++) COMPOBJ_hInstance = hInst;
-                break;
-
-        case DLL_PROCESS_DETACH:
-                if(!--COMPOBJ_Attach)
-                        COMPOBJ_hInstance = 0;
-                break;
-        }
-        return TRUE;
-}
+ *
+ * NOTES: FIXME: protect this with a crst
+ */
+HRESULT WINAPI CoSetState(IUnknown * pv)
+{
+	FIXME("(%p),stub!\n", pv);
+
+	if (pv) {
+	    IUnknown_AddRef(pv);
+	    nStatCounter++;
+	    if (nStatCounter == 1) LoadLibraryA("OLEAUT32.DLL");
+	}
+
+	if (pUnkState) {
+	    TRACE("-- release %p now\n", pUnkState);
+	    IUnknown_Release(pUnkState);
+	    nStatCounter--;
+	    if (!nStatCounter) FreeLibrary(hOleAut32);
+	}
+	pUnkState = pv;
+	return S_OK;
+}
+
 
 /******************************************************************************
@@ -2184,7 +1812,6 @@
     CLSIDFromString(wbuf,pClsidNew);
 done:
-  if (hkey) RegCloseKey(hkey);
-
-  return res;
+    if (hkey) RegCloseKey(hkey);
+    return res;
 }
 
@@ -2262,2 +1889,17 @@
     return !memcmp(rguid1,rguid2,sizeof(GUID));
 }
+
+/***********************************************************************
+ *           CoInitializeSecurity [OLE32.164]
+ */
+HRESULT WINAPI CoInitializeSecurity(PSECURITY_DESCRIPTOR pSecDesc, LONG cAuthSvc,
+                                    SOLE_AUTHENTICATION_SERVICE* asAuthSvc,
+                                    void* pReserved1, DWORD dwAuthnLevel,
+                                    DWORD dwImpLevel, void* pReserved2,
+                                    DWORD dwCapabilities, void* pReserved3)
+{
+  FIXME("(%p,%ld,%p,%p,%ld,%ld,%p,%ld,%p) - stub!\n", pSecDesc, cAuthSvc,
+        asAuthSvc, pReserved1, dwAuthnLevel, dwImpLevel, pReserved2,
+        dwCapabilities, pReserved3);
+  return S_OK;
+}
Index: trunk/src/ole32/compobj_private.h
===================================================================
--- trunk/src/ole32/compobj_private.h	(revision 9394)
+++ trunk/src/ole32/compobj_private.h	(revision 9400)
@@ -125,3 +125,5 @@
 int WINAPI FileMonikerImpl_DecomposePath(LPCOLESTR str, LPOLESTR** stringTable);
 
+HRESULT WINAPI __CLSIDFromStringA(LPCSTR idstr, CLSID *id);
+
 #endif /* __WINE_OLE_COMPOBJ_H */
Index: trunk/src/ole32/datacache.c
===================================================================
--- trunk/src/ole32/datacache.c	(revision 9394)
+++ trunk/src/ole32/datacache.c	(revision 9400)
@@ -827,5 +827,5 @@
 
   if (FAILED(hres))
-    return hres;
+    return (HMETAFILE)hres;
 
   /*
Index: trunk/src/ole32/filemoniker.c
===================================================================
--- trunk/src/ole32/filemoniker.c	(revision 9394)
+++ trunk/src/ole32/filemoniker.c	(revision 9400)
@@ -871,19 +871,16 @@
 
     if (!IsEqualCLSID(&clsid,&CLSID_FileMoniker))
-
         return S_FALSE;
 
-    res=CreateBindCtx(0,&bind);
-    if (FAILED(res))
-        return res;
-
-    IMoniker_GetDisplayName(pmkOtherMoniker,bind,NULL,&filePath);
-
-    if (lstrcmpiW(filePath,
-                  This->filePathName)!=0)
-
-        return S_FALSE;
-
-    return S_OK;
+    res = CreateBindCtx(0,&bind);
+    if (FAILED(res)) return res;
+
+    if (SUCCEEDED(IMoniker_GetDisplayName(pmkOtherMoniker,bind,NULL,&filePath))) {
+	int result = lstrcmpiW(filePath, This->filePathName);
+	CoTaskMemFree(filePath);
+        if ( result == 0 ) return S_OK;
+    }
+    return S_FALSE;
+
 }
 
@@ -1100,4 +1097,6 @@
     int len=lstrlenW(str);
 
+    TRACE("%s, %p\n", debugstr_w(str), *stringTable);
+
     strgtable =CoTaskMemAlloc(len*sizeof(LPOLESTR));
 
Index: trunk/src/ole32/ftmarshal.c
===================================================================
--- trunk/src/ole32/ftmarshal.c	(revision 9400)
+++ trunk/src/ole32/ftmarshal.c	(revision 9400)
@@ -0,0 +1,245 @@
+/*
+ *	free threaded marshaler
+ *
+ *  Copyright 2002  Juergen Schmied
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+
+#include "winbase.h"
+
+#include "wine/obj_base.h"
+#include "wine/obj_storage.h"
+#include "wine/obj_marshal.h"
+
+#include "wine/debug.h"
+
+#ifdef __WIN32OS2__
+#include <winerror.h>
+#endif
+
+WINE_DEFAULT_DEBUG_CHANNEL(ole);
+
+typedef struct _FTMarshalImpl {
+	ICOM_VFIELD (IUnknown);
+	DWORD ref;
+	ICOM_VTABLE (IMarshal) * lpvtblFTM;
+
+	IUnknown *pUnkOuter;
+} FTMarshalImpl;
+
+#define _IFTMUnknown_(This)(IUnknown*)&(This->lpVtbl)
+#define _IFTMarshal_(This) (IMarshal*)&(This->lpvtblFTM)
+
+#define _IFTMarshall_Offset ((int)(&(((FTMarshalImpl*)0)->lpvtblFTM)))
+#define _ICOM_THIS_From_IFTMarshal(class, name) class* This = (class*)(((char*)name)-_IFTMarshall_Offset);
+
+/* inner IUnknown to handle aggregation */
+HRESULT WINAPI IiFTMUnknown_fnQueryInterface (IUnknown * iface, REFIID riid, LPVOID * ppv)
+{
+
+    ICOM_THIS (FTMarshalImpl, iface);
+
+    TRACE ("\n");
+    *ppv = NULL;
+
+    if (IsEqualIID (&IID_IUnknown, riid))
+	*ppv = _IFTMUnknown_ (This);
+    else if (IsEqualIID (&IID_IMarshal, riid))
+	*ppv = _IFTMarshal_ (This);
+    else {
+	FIXME ("No interface for %s.\n", debugstr_guid (riid));
+	return E_NOINTERFACE;
+    }
+    IUnknown_AddRef ((IUnknown *) * ppv);
+    return S_OK;
+}
+
+ULONG WINAPI IiFTMUnknown_fnAddRef (IUnknown * iface)
+{
+
+    ICOM_THIS (FTMarshalImpl, iface);
+
+    TRACE ("\n");
+    return InterlockedIncrement (&This->ref);
+}
+
+ULONG WINAPI IiFTMUnknown_fnRelease (IUnknown * iface)
+{
+
+    ICOM_THIS (FTMarshalImpl, iface);
+
+    TRACE ("\n");
+    if (InterlockedDecrement (&This->ref))
+	return This->ref;
+    HeapFree (GetProcessHeap (), 0, This);
+    return 0;
+}
+
+static ICOM_VTABLE (IUnknown) iunkvt =
+{
+        ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+	IiFTMUnknown_fnQueryInterface,
+	IiFTMUnknown_fnAddRef,
+	IiFTMUnknown_fnRelease
+};
+
+HRESULT WINAPI FTMarshalImpl_QueryInterface (LPMARSHAL iface, REFIID riid, LPVOID * ppv)
+{
+
+    _ICOM_THIS_From_IFTMarshal (FTMarshalImpl, iface);
+
+    TRACE ("(%p)->(\n\tIID:\t%s,%p)\n", This, debugstr_guid (riid), ppv);
+    return IUnknown_QueryInterface (This->pUnkOuter, riid, ppv);
+}
+
+ULONG WINAPI FTMarshalImpl_AddRef (LPMARSHAL iface)
+{
+
+    _ICOM_THIS_From_IFTMarshal (FTMarshalImpl, iface);
+
+    TRACE ("\n");
+    return IUnknown_AddRef (This->pUnkOuter);
+}
+
+ULONG WINAPI FTMarshalImpl_Release (LPMARSHAL iface)
+{
+
+    _ICOM_THIS_From_IFTMarshal (FTMarshalImpl, iface);
+
+    TRACE ("\n");
+    return IUnknown_Release (This->pUnkOuter);
+}
+
+HRESULT WINAPI FTMarshalImpl_GetUnmarshalClass (LPMARSHAL iface, REFIID riid, void *pv, DWORD dwDestContext,
+						void *pvDestContext, DWORD mshlflags, CLSID * pCid)
+{
+    FIXME ("(), stub!\n");
+    return S_OK;
+}
+
+HRESULT WINAPI FTMarshalImpl_GetMarshalSizeMax (LPMARSHAL iface, REFIID riid, void *pv, DWORD dwDestContext,
+						void *pvDestContext, DWORD mshlflags, DWORD * pSize)
+{
+
+    IMarshal *pMarshal = NULL;
+    HRESULT hres;
+
+    _ICOM_THIS_From_IFTMarshal (FTMarshalImpl, iface);
+
+    FIXME ("(), stub!\n");
+
+    /* if the marshaling happends inside the same process the interface pointer is
+       copied between the appartments */
+    if (dwDestContext == MSHCTX_INPROC || dwDestContext == MSHCTX_CROSSCTX) {
+	*pSize = sizeof (This);
+	return S_OK;
+    }
+
+    /* use the standard marshaler to handle all other cases */
+    CoGetStandardMarshal (riid, pv, dwDestContext, pvDestContext, mshlflags, &pMarshal);
+    hres = IMarshal_GetMarshalSizeMax (pMarshal, riid, pv, dwDestContext, pvDestContext, mshlflags, pSize);
+    IMarshal_Release (pMarshal);
+    return hres;
+
+    return S_OK;
+}
+
+HRESULT WINAPI FTMarshalImpl_MarshalInterface (LPMARSHAL iface, IStream * pStm, REFIID riid, void *pv,
+					       DWORD dwDestContext, void *pvDestContext, DWORD mshlflags)
+{
+
+    IMarshal *pMarshal = NULL;
+    HRESULT hres;
+
+    _ICOM_THIS_From_IFTMarshal (FTMarshalImpl, iface);
+
+    FIXME ("(), stub!\n");
+
+    /* if the marshaling happends inside the same process the interface pointer is
+       copied between the appartments */
+    if (dwDestContext == MSHCTX_INPROC || dwDestContext == MSHCTX_CROSSCTX) {
+	return IStream_Write (pStm, This, sizeof (This), 0);
+    }
+
+    /* use the standard marshaler to handle all other cases */
+    CoGetStandardMarshal (riid, pv, dwDestContext, pvDestContext, mshlflags, &pMarshal);
+    hres = IMarshal_MarshalInterface (pMarshal, pStm, riid, pv, dwDestContext, pvDestContext, mshlflags);
+    IMarshal_Release (pMarshal);
+    return hres;
+}
+
+HRESULT WINAPI FTMarshalImpl_UnmarshalInterface (LPMARSHAL iface, IStream * pStm, REFIID riid, void **ppv)
+{
+    FIXME ("(), stub!\n");
+    return S_OK;
+}
+
+HRESULT WINAPI FTMarshalImpl_ReleaseMarshalData (LPMARSHAL iface, IStream * pStm)
+{
+    FIXME ("(), stub!\n");
+    return S_OK;
+}
+
+HRESULT WINAPI FTMarshalImpl_DisconnectObject (LPMARSHAL iface, DWORD dwReserved)
+{
+    FIXME ("(), stub!\n");
+    return S_OK;
+}
+
+ICOM_VTABLE (IMarshal) ftmvtbl =
+{
+        ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+	FTMarshalImpl_QueryInterface,
+	FTMarshalImpl_AddRef,
+	FTMarshalImpl_Release,
+	FTMarshalImpl_GetUnmarshalClass,
+	FTMarshalImpl_GetMarshalSizeMax,
+	FTMarshalImpl_MarshalInterface,
+	FTMarshalImpl_UnmarshalInterface,
+	FTMarshalImpl_ReleaseMarshalData,
+	FTMarshalImpl_DisconnectObject
+};
+
+/***********************************************************************
+ *          CoCreateFreeThreadedMarshaler [OLE32.5]
+ *
+ */
+HRESULT WINAPI CoCreateFreeThreadedMarshaler (LPUNKNOWN punkOuter, LPUNKNOWN * ppunkMarshal)
+{
+
+    FTMarshalImpl *ftm;
+
+    TRACE ("(%p %p)\n", punkOuter, ppunkMarshal);
+
+    ftm = (FTMarshalImpl *) HeapAlloc (GetProcessHeap (), 0, sizeof (FTMarshalImpl));
+    if (!ftm)
+	return E_OUTOFMEMORY;
+
+    ICOM_VTBL (ftm) = &iunkvt;
+    ftm->lpvtblFTM = &ftmvtbl;
+    ftm->ref = 1;
+    ftm->pUnkOuter = punkOuter;
+
+    *ppunkMarshal = _IFTMUnknown_ (ftm);
+    return S_OK;
+}
Index: trunk/src/ole32/hglobalstream.c
===================================================================
--- trunk/src/ole32/hglobalstream.c	(revision 9394)
+++ trunk/src/ole32/hglobalstream.c	(revision 9400)
@@ -34,4 +34,5 @@
 #include "winbase.h"
 #include "winerror.h"
+#include "winternl.h"
 
 #include "wine/debug.h"
@@ -574,14 +575,4 @@
 
   /*
-   * The caller is allowed to pass in NULL as the new position return value.
-   * If it happens, we assign it to a dynamic variable to avoid special cases
-   * in the code below.
-   */
-  if (plibNewPosition == 0)
-  {
-    plibNewPosition = &newPosition;
-  }
-
-  /*
    * The file pointer is moved depending on the given "function"
    * parameter.
@@ -590,12 +581,12 @@
   {
     case STREAM_SEEK_SET:
-      plibNewPosition->s.HighPart = 0;
-      plibNewPosition->s.LowPart  = 0;
+      newPosition.s.HighPart = 0;
+      newPosition.s.LowPart = 0;
       break;
     case STREAM_SEEK_CUR:
-      *plibNewPosition = This->currentPosition;
+      newPosition = This->currentPosition;
       break;
     case STREAM_SEEK_END:
-      *plibNewPosition = This->streamSize;
+      newPosition = This->streamSize;
       break;
     default:
@@ -604,27 +595,17 @@
 
   /*
-   * We don't support files with offsets of 64 bits.
-   */
-  assert(dlibMove.s.HighPart == 0);
-
-  /*
-   * Check if we end-up before the beginning of the file. That should trigger an
-   * error.
-   */
-  if ( (dlibMove.s.LowPart<0) && (plibNewPosition->s.LowPart < (ULONG)(-dlibMove.s.LowPart)) )
-  {
-    /*
-     * I don't know what error to send there.
-     */
-    return E_FAIL;
-  }
-
-  /*
    * Move the actual file pointer
    * If the file pointer ends-up after the end of the stream, the next Write operation will
    * make the file larger. This is how it is documented.
    */
-  plibNewPosition->s.LowPart += dlibMove.s.LowPart;
-  This->currentPosition = *plibNewPosition;
+#ifdef __WIN32OS2__
+  *(LARGE_INTEGER *)&newPosition = RtlpLargeIntegerAdd( (LARGE_INTEGER *)&newPosition, &dlibMove );
+#else
+  newPosition.QuadPart = RtlLargeIntegerAdd(newPosition.QuadPart, dlibMove.QuadPart);
+#endif
+  if (newPosition.QuadPart < 0) return STG_E_INVALIDFUNCTION;
+
+  if (plibNewPosition) *plibNewPosition = newPosition;
+  This->currentPosition = newPosition;
 
   return S_OK;
@@ -844,5 +825,14 @@
 		  IStream**    ppstm) /* [out] */
 {
-  FIXME("not implemented!\n");
-  return E_NOTIMPL;
-}
+  ULARGE_INTEGER dummy;
+  LARGE_INTEGER offset;
+  HRESULT hr;
+  HGLOBALStreamImpl* const This=(HGLOBALStreamImpl*)iface;
+  TRACE(" Cloning %p (deleteOnRelease=%d seek position=%ld)\n",iface,This->deleteOnRelease,(long)This->currentPosition.QuadPart);
+  hr=CreateStreamOnHGlobal(This->supportHandle, FALSE, ppstm);
+  if(FAILED(hr))
+    return hr;
+  offset.QuadPart=(LONGLONG)This->currentPosition.QuadPart;
+  HGLOBALStreamImpl_Seek(*ppstm,offset,STREAM_SEEK_SET,&dummy);
+  return S_OK;
+}
Index: trunk/src/ole32/ifs.c
===================================================================
--- trunk/src/ole32/ifs.c	(revision 9394)
+++ trunk/src/ole32/ifs.c	(revision 9400)
@@ -28,350 +28,586 @@
 #include "ole2.h"
 #include "windef.h"
+#include "winbase.h"
 #include "winerror.h"
 
 #include "wine/obj_base.h"
-#include "wine/winbase16.h"
-#include "ifs.h"
 
 #include "wine/debug.h"
 
-WINE_DEFAULT_DEBUG_CHANNEL(relay);
-
-/* --- IUnknown implementation */
-
-typedef struct
-{
-    /* IUnknown fields */
-    ICOM_VFIELD(IUnknown);
-    DWORD                  ref;
-} IUnknownImpl;
-
-/******************************************************************************
- *		IUnknown_AddRef	[VTABLE:IUNKNOWN.1]
- */
-static ULONG WINAPI IUnknown_fnAddRef(LPUNKNOWN iface) { 
-	ICOM_THIS(IUnknownImpl,iface);
-	TRACE("(%p)->AddRef()\n",This);
-	return ++(This->ref);
-}
-
-/******************************************************************************
- * IUnknown_Release [VTABLE:IUNKNOWN.2]
- */
-static ULONG WINAPI IUnknown_fnRelease(LPUNKNOWN iface) {
-	ICOM_THIS(IUnknownImpl,iface);
-	TRACE("(%p)->Release()\n",This);
-	if (!--(This->ref)) {
-		HeapFree(GetProcessHeap(),0,This);
-		return 0;
-	}
-	return This->ref;
-}
-
-/******************************************************************************
- * IUnknown_QueryInterface [VTABLE:IUNKNOWN.0]
- */
-static HRESULT WINAPI IUnknown_fnQueryInterface(LPUNKNOWN iface,REFIID refiid,LPVOID *obj) {
-	ICOM_THIS(IUnknownImpl,iface);
-
-	TRACE("(%p)->QueryInterface(%s,%p)\n",This,debugstr_guid(refiid),obj);
-
-	if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
-		*obj = This;
-		return 0; 
-	}
-	return OLE_E_ENUM_NOMORE; 
-}
-
-static ICOM_VTABLE(IUnknown) uvt = 
+#ifdef __WIN32OS2__
+#define CRITICAL_SECTION_INIT(name) { (void *)(__FILE__ ": " name), -1, 0, 0, 0, 0 }
+#endif
+
+WINE_DEFAULT_DEBUG_CHANNEL(ole);
+
+/******************************************************************************
+ *	IMalloc32 implementation
+ *
+ * NOTES
+ *  For supporting CoRegisterMallocSpy the IMalloc implementation must know if
+ *  a given memory block was allocated with a spy active.
+ *
+ *****************************************************************************/
+/* set the vtable later */
+extern ICOM_VTABLE(IMalloc) VT_IMalloc32;
+
+typedef struct {
+        ICOM_VFIELD(IMalloc);
+        DWORD dummy;                /* nothing, we are static */
+	IMallocSpy * pSpy;          /* the spy when active */
+	DWORD SpyedAllocationsLeft; /* number of spyed allocations left */
+	BOOL SpyReleasePending;     /* CoRevokeMallocSpy called with spyed allocations left*/
+        LPVOID * SpyedBlocks;       /* root of the table */
+        int SpyedBlockTableLength;  /* size of the table*/
+} _Malloc32;
+
+/* this is the static object instance */
+_Malloc32 Malloc32 = {&VT_IMalloc32, 0, NULL, 0, 0, NULL, 0};
+
+/* with a spy active all calls from pre to post methods are threadsave */
+static CRITICAL_SECTION IMalloc32_SpyCS = CRITICAL_SECTION_INIT("IMalloc32_SpyCS");
+
+/* resize the old table */
+static int SetSpyedBlockTableLength ( int NewLength )
+{
+        Malloc32.SpyedBlocks = (LPVOID*)LocalReAlloc((HLOCAL)Malloc32.SpyedBlocks, NewLength, GMEM_ZEROINIT);
+        Malloc32.SpyedBlockTableLength = NewLength;
+        return Malloc32.SpyedBlocks ? 1 : 0;
+}
+
+/* add a location to the table */
+static int AddMemoryLocation(LPVOID * pMem)
+{
+        LPVOID * Current;
+
+	/* allocate the table if not already allocated */
+	if (!Malloc32.SpyedBlockTableLength) {
+            if (!SetSpyedBlockTableLength(0x1000)) return 0;
+	}
+
+	/* find a free location */
+	Current = Malloc32.SpyedBlocks;
+	while (*Current) {
+            Current++;
+	    if (Current >= Malloc32.SpyedBlocks + Malloc32.SpyedBlockTableLength) {
+	        /* no more space in table, grow it */
+	        if (!SetSpyedBlockTableLength( Malloc32.SpyedBlockTableLength + 0x1000 )) return 0;
+	    }
+	};
+
+	/* put the location in our table */
+	*Current = pMem;
+        Malloc32.SpyedAllocationsLeft++;
+	/*TRACE("%lu\n",Malloc32.SpyedAllocationsLeft);*/
+        return 1;
+}
+
+static int RemoveMemoryLocation(LPVOID * pMem)
+{
+        LPVOID * Current = Malloc32.SpyedBlocks;
+
+	/* find the location */
+	while (*Current != pMem) {
+            Current++;
+	    if (Current >= Malloc32.SpyedBlocks + Malloc32.SpyedBlockTableLength)  return 0;      /* not found  */
+	}
+
+	/* location found */
+        Malloc32.SpyedAllocationsLeft--;
+	/*TRACE("%lu\n",Malloc32.SpyedAllocationsLeft);*/
+	*Current = NULL;
+	return 1;
+}
+
+/******************************************************************************
+ *	IMalloc32_QueryInterface	[VTABLE]
+ */
+static HRESULT WINAPI IMalloc_fnQueryInterface(LPMALLOC iface,REFIID refiid,LPVOID *obj) {
+
+	TRACE("(%s,%p)\n",debugstr_guid(refiid),obj);
+
+	if (IsEqualIID(&IID_IUnknown,refiid) || IsEqualIID(&IID_IMalloc,refiid)) {
+		*obj = (LPMALLOC)&Malloc32;
+		return S_OK;
+	}
+	return E_NOINTERFACE;
+}
+
+/******************************************************************************
+ *	IMalloc32_AddRefRelease		[VTABLE]
+ */
+static ULONG WINAPI IMalloc_fnAddRefRelease (LPMALLOC iface) {
+	return 1;
+}
+
+/******************************************************************************
+ *	IMalloc32_Alloc 		[VTABLE]
+ */
+static LPVOID WINAPI IMalloc_fnAlloc(LPMALLOC iface, DWORD cb) {
+
+	LPVOID addr;
+
+	TRACE("(%ld)\n",cb);
+
+	if(Malloc32.pSpy) {
+	    EnterCriticalSection(&IMalloc32_SpyCS);
+	    cb = IMallocSpy_PreAlloc(Malloc32.pSpy, cb);
+	    if (0==cb) {
+	        /* PreAlloc can force Alloc to fail */
+	        LeaveCriticalSection(&IMalloc32_SpyCS);
+		return NULL;
+	    }
+	}
+
+
+	addr = HeapAlloc(GetProcessHeap(),0,cb);
+
+	if(Malloc32.pSpy) {
+	    addr = IMallocSpy_PostAlloc(Malloc32.pSpy, addr);
+	    if (addr) AddMemoryLocation(addr);
+	    LeaveCriticalSection(&IMalloc32_SpyCS);
+	}
+
+	TRACE("--(%p)\n",addr);
+	return addr;
+}
+
+/******************************************************************************
+ * IMalloc32_Realloc [VTABLE]
+ */
+static LPVOID WINAPI IMalloc_fnRealloc(LPMALLOC iface,LPVOID pv,DWORD cb) {
+
+	LPVOID pNewMemory;
+
+	TRACE("(%p,%ld)\n",pv,cb);
+
+	if(Malloc32.pSpy) {
+	    LPVOID pRealMemory;
+	    BOOL fSpyed;
+
+	    EnterCriticalSection(&IMalloc32_SpyCS);
+            fSpyed = RemoveMemoryLocation(pv);
+            cb = IMallocSpy_PreRealloc(Malloc32.pSpy, pv, cb, &pRealMemory, fSpyed);
+
+	    /* check if can release the spy */
+	    if(Malloc32.SpyReleasePending && !Malloc32.SpyedAllocationsLeft) {
+	        IMallocSpy_Release(Malloc32.pSpy);
+		Malloc32.SpyReleasePending = FALSE;
+		Malloc32.pSpy = NULL;
+	    }
+
+	    if (0==cb) {
+	        /* PreRealloc can force Realloc to fail */
+                LeaveCriticalSection(&IMalloc32_SpyCS);
+		return NULL;
+	    }
+	    pv = pRealMemory;
+	}
+
+	pNewMemory = HeapReAlloc(GetProcessHeap(),0,pv,cb);
+
+	if(Malloc32.pSpy) {
+	    pNewMemory = IMallocSpy_PostRealloc(Malloc32.pSpy, pNewMemory, TRUE);
+	    if (pNewMemory) AddMemoryLocation(pNewMemory);
+            LeaveCriticalSection(&IMalloc32_SpyCS);
+	}
+
+	TRACE("--(%p)\n",pNewMemory);
+	return pNewMemory;
+}
+
+/******************************************************************************
+ * IMalloc32_Free [VTABLE]
+ */
+static VOID WINAPI IMalloc_fnFree(LPMALLOC iface,LPVOID pv) {
+
+	BOOL fSpyed = 0;
+
+	TRACE("(%p)\n",pv);
+
+	if(Malloc32.pSpy) {
+            EnterCriticalSection(&IMalloc32_SpyCS);
+            fSpyed = RemoveMemoryLocation(pv);
+	    pv = IMallocSpy_PreFree(Malloc32.pSpy, pv, fSpyed);
+	}
+
+	HeapFree(GetProcessHeap(),0,pv);
+
+	if(Malloc32.pSpy) {
+	    IMallocSpy_PostFree(Malloc32.pSpy, fSpyed);
+
+	    /* check if can release the spy */
+	    if(Malloc32.SpyReleasePending && !Malloc32.SpyedAllocationsLeft) {
+	        IMallocSpy_Release(Malloc32.pSpy);
+		Malloc32.SpyReleasePending = FALSE;
+		Malloc32.pSpy = NULL;
+	    }
+
+	    LeaveCriticalSection(&IMalloc32_SpyCS);
+        }
+}
+
+/******************************************************************************
+ * IMalloc32_GetSize [VTABLE]
+ *
+ * NOTES
+ *  FIXME returns:
+ *      win95:  size allocated (4 byte boundarys)
+ *      win2k:  size originally requested !!! (allocated on 8 byte boundarys)
+ */
+static DWORD WINAPI IMalloc_fnGetSize(LPMALLOC iface,LPVOID pv) {
+
+	DWORD cb;
+	BOOL fSpyed = 0;
+
+	TRACE("(%p)\n",pv);
+
+	if(Malloc32.pSpy) {
+            EnterCriticalSection(&IMalloc32_SpyCS);
+	    pv = IMallocSpy_PreGetSize(Malloc32.pSpy, pv, fSpyed);
+	}
+
+	cb = HeapSize(GetProcessHeap(),0,pv);
+
+	if(Malloc32.pSpy) {
+	    cb = IMallocSpy_PostGetSize(Malloc32.pSpy, cb, fSpyed);
+	    LeaveCriticalSection(&IMalloc32_SpyCS);
+	}
+
+	return cb;
+}
+
+/******************************************************************************
+ * IMalloc32_DidAlloc [VTABLE]
+ */
+static INT WINAPI IMalloc_fnDidAlloc(LPMALLOC iface,LPVOID pv) {
+
+	BOOL fSpyed = 0;
+	int didAlloc;
+
+	TRACE("(%p)\n",pv);
+
+	if(Malloc32.pSpy) {
+            EnterCriticalSection(&IMalloc32_SpyCS);
+	    pv = IMallocSpy_PreDidAlloc(Malloc32.pSpy, pv, fSpyed);
+	}
+
+	didAlloc = -1;
+
+	if(Malloc32.pSpy) {
+	    didAlloc = IMallocSpy_PostDidAlloc(Malloc32.pSpy, pv, fSpyed, didAlloc);
+            LeaveCriticalSection(&IMalloc32_SpyCS);
+	}
+	return didAlloc;
+}
+
+/******************************************************************************
+ * IMalloc32_HeapMinimize [VTABLE]
+ */
+static VOID WINAPI IMalloc_fnHeapMinimize(LPMALLOC iface) {
+	TRACE("()\n");
+
+	if(Malloc32.pSpy) {
+            EnterCriticalSection(&IMalloc32_SpyCS);
+	    IMallocSpy_PreHeapMinimize(Malloc32.pSpy);
+	}
+
+	if(Malloc32.pSpy) {
+	    IMallocSpy_PostHeapMinimize(Malloc32.pSpy);
+            LeaveCriticalSection(&IMalloc32_SpyCS);
+	}
+}
+
+#ifdef __WIN32OS2__
+       ICOM_VTABLE(IMalloc) VT_IMalloc32 =
+#else
+static ICOM_VTABLE(IMalloc) VT_IMalloc32 =
+#endif
 {
 	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
-	IUnknown_fnQueryInterface,
-	IUnknown_fnAddRef,
-	IUnknown_fnRelease
+	IMalloc_fnQueryInterface,
+	IMalloc_fnAddRefRelease,
+	IMalloc_fnAddRefRelease,
+	IMalloc_fnAlloc,
+	IMalloc_fnRealloc,
+	IMalloc_fnFree,
+	IMalloc_fnGetSize,
+	IMalloc_fnDidAlloc,
+	IMalloc_fnHeapMinimize
 };
 
 /******************************************************************************
- * IUnknown_Constructor [INTERNAL]
- */
-LPUNKNOWN
-IUnknown_Constructor() {
-	IUnknownImpl*	unk;
-
-	unk = (IUnknownImpl*)HeapAlloc(GetProcessHeap(),0,sizeof(IUnknownImpl));
-	ICOM_VTBL(unk)	= &uvt;
-	unk->ref	= 1;
-	return (LPUNKNOWN)unk;
-}
-
-#ifndef __WIN32OS2__
-/* --- IMalloc16 implementation */
-
-
-typedef struct
-{
-        /* IUnknown fields */
-        ICOM_VFIELD(IMalloc16);
-        DWORD                   ref;
-        /* IMalloc16 fields */
-} IMalloc16Impl;
-
-/******************************************************************************
- *		IMalloc16_QueryInterface	[COMPOBJ.500]
- */
-HRESULT WINAPI IMalloc16_fnQueryInterface(IMalloc16* iface,REFIID refiid,LPVOID *obj) {
-        ICOM_THIS(IMalloc16Impl,iface);
-
-	TRACE("(%p)->QueryInterface(%s,%p)\n",This,debugstr_guid(refiid),obj);
-	if (	!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown)) ||
-		!memcmp(&IID_IMalloc,refiid,sizeof(IID_IMalloc))
-	) {
-		*obj = This;
-		return 0;
-	}
-	return OLE_E_ENUM_NOMORE; 
-}
-
-/******************************************************************************
- *		IMalloc16_AddRef	[COMPOBJ.501]
- */
-ULONG WINAPI IMalloc16_fnAddRef(IMalloc16* iface) {
-        ICOM_THIS(IMalloc16Impl,iface);
-	TRACE("(%p)->AddRef()\n",This);
-	return 1; /* cannot be freed */
-}
-
-/******************************************************************************
- *		IMalloc16_Release	[COMPOBJ.502]
- */
-ULONG WINAPI IMalloc16_fnRelease(IMalloc16* iface) {
-        ICOM_THIS(IMalloc16Impl,iface);
-	TRACE("(%p)->Release()\n",This);
-	return 1; /* cannot be freed */
-}
-
-/******************************************************************************
- * IMalloc16_Alloc [COMPOBJ.503]
- */
-SEGPTR WINAPI IMalloc16_fnAlloc(IMalloc16* iface,DWORD cb) {
-        ICOM_THIS(IMalloc16Impl,iface);
-	TRACE("(%p)->Alloc(%ld)\n",This,cb);
-        return MapLS( HeapAlloc( GetProcessHeap(), 0, cb ) );
-}
-
-/******************************************************************************
- * IMalloc16_Realloc [COMPOBJ.504]
- */
-SEGPTR WINAPI IMalloc16_fnRealloc(IMalloc16* iface,SEGPTR pv,DWORD cb)
-{
-    SEGPTR ret;
-    ICOM_THIS(IMalloc16Impl,iface);
-    TRACE("(%p)->Realloc(%08lx,%ld)\n",This,pv,cb);
-    ret = MapLS( HeapReAlloc( GetProcessHeap(), 0, MapSL(pv), cb ) );
-    UnMapLS(pv);
-    return ret;
-}
-
-/******************************************************************************
- * IMalloc16_Free [COMPOBJ.505]
- */
-VOID WINAPI IMalloc16_fnFree(IMalloc16* iface,SEGPTR pv)
-{
-    void *ptr = MapSL(pv);
-    ICOM_THIS(IMalloc16Impl,iface);
-    TRACE("(%p)->Free(%08lx)\n",This,pv);
-    UnMapLS(pv);
-    HeapFree( GetProcessHeap(), 0, ptr );
-}
-
-/******************************************************************************
- * IMalloc16_GetSize [COMPOBJ.506]
- */
-DWORD WINAPI IMalloc16_fnGetSize(const IMalloc16* iface,SEGPTR pv)
-{
-	ICOM_CTHIS(IMalloc16Impl,iface);
-        TRACE("(%p)->GetSize(%08lx)\n",This,pv);
-        return HeapSize( GetProcessHeap(), 0, MapSL(pv) );
-}
-
-/******************************************************************************
- * IMalloc16_DidAlloc [COMPOBJ.507]
- */
-INT16 WINAPI IMalloc16_fnDidAlloc(const IMalloc16* iface,LPVOID pv) {
-        ICOM_CTHIS(IMalloc16,iface);
-	TRACE("(%p)->DidAlloc(%p)\n",This,pv);
-	return (INT16)-1;
-}
-
-/******************************************************************************
- * IMalloc16_HeapMinimize [COMPOBJ.508]
- */
-LPVOID WINAPI IMalloc16_fnHeapMinimize(IMalloc16* iface) {
-        ICOM_THIS(IMalloc16Impl,iface);
-	TRACE("(%p)->HeapMinimize()\n",This);
-	return NULL;
-}
-
-/******************************************************************************
- * IMalloc16_Constructor [VTABLE]
- */
-LPMALLOC16
-IMalloc16_Constructor()
-{
-    static ICOM_VTABLE(IMalloc16) vt16;
-    static SEGPTR msegvt16;
-    IMalloc16Impl* This;
-    HMODULE16 hcomp = GetModuleHandle16("COMPOBJ");
-
-    This = HeapAlloc( GetProcessHeap(), 0, sizeof(IMalloc16Impl) );
-    if (!msegvt16)
-    {
-#define VTENT(x) vt16.x = (void*)GetProcAddress16(hcomp,"IMalloc16_"#x);assert(vt16.x)
-        VTENT(QueryInterface);
-        VTENT(AddRef);
-        VTENT(Release);
-        VTENT(Alloc);
-        VTENT(Realloc);
-        VTENT(Free);
-        VTENT(GetSize);
-        VTENT(DidAlloc);
-        VTENT(HeapMinimize);
-#undef VTENT
-        msegvt16 = MapLS( &vt16 );
+ *	IMallocSpy implementation
+ *****************************************************************************/
+
+/* set the vtable later */
+extern ICOM_VTABLE(IMallocSpy) VT_IMallocSpy;
+
+typedef struct {
+        ICOM_VFIELD(IMallocSpy);
+        DWORD ref;
+} _MallocSpy;
+
+/* this is the static object instance */
+_MallocSpy MallocSpy = {&VT_IMallocSpy, 0};
+
+/******************************************************************************
+ *	IMalloc32_QueryInterface	[VTABLE]
+ */
+static HRESULT WINAPI IMallocSpy_fnQueryInterface(LPMALLOCSPY iface,REFIID refiid,LPVOID *obj)
+{
+
+	TRACE("(%s,%p)\n",debugstr_guid(refiid),obj);
+
+	if (IsEqualIID(&IID_IUnknown,refiid) || IsEqualIID(&IID_IMallocSpy,refiid)) {
+		*obj = (LPMALLOC)&MallocSpy;
+		return S_OK;
+	}
+	return E_NOINTERFACE;
+}
+
+/******************************************************************************
+ *	IMalloc32_AddRef		[VTABLE]
+ */
+static ULONG WINAPI IMallocSpy_fnAddRef (LPMALLOCSPY iface)
+{
+
+    ICOM_THIS (_MallocSpy, iface);
+
+    TRACE ("(%p)->(count=%lu)\n", This, This->ref);
+
+    return ++(This->ref);
+}
+
+/******************************************************************************
+ *	IMalloc32_AddRelease		[VTABLE]
+ *
+ * NOTES
+ *   Our MallocSpy is static. If the count reaches 0 we dump the leaks
+ */
+static ULONG WINAPI IMallocSpy_fnRelease (LPMALLOCSPY iface)
+{
+
+    ICOM_THIS (_MallocSpy, iface);
+
+    TRACE ("(%p)->(count=%lu)\n", This, This->ref);
+
+    if (!--(This->ref)) {
+        /* our allocation list MUST be empty here */
     }
-    ICOM_VTBL(This) = (ICOM_VTABLE(IMalloc16)*)msegvt16;
-    This->ref = 1;
-    return (LPMALLOC16)MapLS( This );
-}
+    return This->ref;
+}
+
+static ULONG WINAPI IMallocSpy_fnPreAlloc(LPMALLOCSPY iface, ULONG cbRequest)
+{
+    ICOM_THIS (_MallocSpy, iface);
+    TRACE ("(%p)->(%lu)\n", This, cbRequest);
+    return cbRequest;
+}
+static PVOID WINAPI IMallocSpy_fnPostAlloc(LPMALLOCSPY iface, void* pActual)
+{
+    ICOM_THIS (_MallocSpy, iface);
+    TRACE ("(%p)->(%p)\n", This, pActual);
+    return pActual;
+}
+
+static PVOID WINAPI IMallocSpy_fnPreFree(LPMALLOCSPY iface, void* pRequest, BOOL fSpyed)
+{
+    ICOM_THIS (_MallocSpy, iface);
+    TRACE ("(%p)->(%p %u)\n", This, pRequest, fSpyed);
+    return pRequest;
+}
+static void  WINAPI IMallocSpy_fnPostFree(LPMALLOCSPY iface, BOOL fSpyed)
+{
+    ICOM_THIS (_MallocSpy, iface);
+    TRACE ("(%p)->(%u)\n", This, fSpyed);
+}
+
+static ULONG WINAPI IMallocSpy_fnPreRealloc(LPMALLOCSPY iface, void* pRequest, ULONG cbRequest, void** ppNewRequest, BOOL fSpyed)
+{
+    ICOM_THIS (_MallocSpy, iface);
+    TRACE ("(%p)->(%p %lu %u)\n", This, pRequest, cbRequest, fSpyed);
+    *ppNewRequest = pRequest;
+    return cbRequest;
+}
+
+static PVOID WINAPI IMallocSpy_fnPostRealloc(LPMALLOCSPY iface, void* pActual, BOOL fSpyed)
+{
+    ICOM_THIS (_MallocSpy, iface);
+    TRACE ("(%p)->(%p %u)\n", This, pActual, fSpyed);
+    return pActual;
+}
+
+static PVOID WINAPI IMallocSpy_fnPreGetSize(LPMALLOCSPY iface, void* pRequest, BOOL fSpyed)
+{
+    ICOM_THIS (_MallocSpy, iface);
+    TRACE ("(%p)->(%p %u)\n", This,  pRequest, fSpyed);
+    return pRequest;
+}
+
+static ULONG WINAPI IMallocSpy_fnPostGetSize(LPMALLOCSPY iface, ULONG cbActual, BOOL fSpyed)
+{
+    ICOM_THIS (_MallocSpy, iface);
+    TRACE ("(%p)->(%lu %u)\n", This, cbActual, fSpyed);
+    return cbActual;
+}
+
+static PVOID WINAPI IMallocSpy_fnPreDidAlloc(LPMALLOCSPY iface, void* pRequest, BOOL fSpyed)
+{
+    ICOM_THIS (_MallocSpy, iface);
+    TRACE ("(%p)->(%p %u)\n", This, pRequest, fSpyed);
+    return pRequest;
+}
+
+static int WINAPI IMallocSpy_fnPostDidAlloc(LPMALLOCSPY iface, void* pRequest, BOOL fSpyed, int fActual)
+{
+    ICOM_THIS (_MallocSpy, iface);
+    TRACE ("(%p)->(%p %u %u)\n", This, pRequest, fSpyed, fActual);
+    return fActual;
+}
+
+static int WINAPI IMallocSpy_fnPreHeapMinimize(LPMALLOCSPY iface)
+{
+    ICOM_THIS (_MallocSpy, iface);
+    TRACE ("(%p)->()\n", This);
+    return 0;
+}
+
+static int WINAPI IMallocSpy_fnPostHeapMinimize(LPMALLOCSPY iface)
+{
+    ICOM_THIS (_MallocSpy, iface);
+    TRACE ("(%p)->()\n", This);
+    return 0;
+}
+
+static void MallocSpyDumpLeaks() {
+        TRACE("leaks: %lu\n", Malloc32.SpyedAllocationsLeft);
+}
+
+#ifdef __WIN32OS2__
+       ICOM_VTABLE(IMallocSpy) VT_IMallocSpy =
+#else
+static ICOM_VTABLE(IMallocSpy) VT_IMallocSpy =
 #endif
-
-/* --- IMalloc32 implementation */
-
-typedef struct
-{
-        /* IUnknown fields */
-        ICOM_VFIELD(IMalloc);
-        DWORD                   ref;
-} IMalloc32Impl;
-
-/******************************************************************************
- *		IMalloc32_QueryInterface	[VTABLE]
- */
-static HRESULT WINAPI IMalloc_fnQueryInterface(LPMALLOC iface,REFIID refiid,LPVOID *obj) {
-	ICOM_THIS(IMalloc32Impl,iface);
-
-	TRACE("(%p)->QueryInterface(%s,%p)\n",This,debugstr_guid(refiid),obj);
-	if (	!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown)) ||
-		!memcmp(&IID_IMalloc,refiid,sizeof(IID_IMalloc))
-	) {
-		*obj = This;
-		return S_OK;
-	}
-	return OLE_E_ENUM_NOMORE; 
-}
-
-/******************************************************************************
- *		IMalloc32_AddRef	[VTABLE]
- */
-static ULONG WINAPI IMalloc_fnAddRef(LPMALLOC iface) {
-	ICOM_THIS(IMalloc32Impl,iface);
-	TRACE("(%p)->AddRef()\n",This);
-	return 1; /* cannot be freed */
-}
-
-/******************************************************************************
- *		IMalloc32_Release	[VTABLE]
- */
-static ULONG WINAPI IMalloc_fnRelease(LPMALLOC iface) {
-	ICOM_THIS(IMalloc32Impl,iface);
-	TRACE("(%p)->Release()\n",This);
-	return 1; /* cannot be freed */
-}
-
-/******************************************************************************
- * IMalloc32_Alloc [VTABLE]
- */
-static LPVOID WINAPI IMalloc_fnAlloc(LPMALLOC iface,DWORD cb) {
-	LPVOID addr;
-	ICOM_THIS(IMalloc32Impl,iface);
-	addr = HeapAlloc(GetProcessHeap(),0,cb);
-	TRACE("(%p)->Alloc(%ld) -> %p\n",This,cb,addr);
-	return addr;
-}
-
-/******************************************************************************
- * IMalloc32_Realloc [VTABLE]
- */
-static LPVOID WINAPI IMalloc_fnRealloc(LPMALLOC iface,LPVOID pv,DWORD cb) {
-	ICOM_THIS(IMalloc32Impl,iface);
-	TRACE("(%p)->Realloc(%p,%ld)\n",This,pv,cb);
-	return HeapReAlloc(GetProcessHeap(),0,pv,cb);
-}
-
-/******************************************************************************
- * IMalloc32_Free [VTABLE]
- */
-static VOID WINAPI IMalloc_fnFree(LPMALLOC iface,LPVOID pv) {
-	ICOM_THIS(IMalloc32Impl,iface);
-	TRACE("(%p)->Free(%p)\n",This,pv);
-	HeapFree(GetProcessHeap(),0,pv);
-}
-
-/******************************************************************************
- * IMalloc32_GetSize [VTABLE]
- */
-static DWORD WINAPI IMalloc_fnGetSize(LPMALLOC iface,LPVOID pv) {
-	ICOM_CTHIS(IMalloc,iface);
-	TRACE("(%p)->GetSize(%p)\n",This,pv);
-	return HeapSize(GetProcessHeap(),0,pv);
-}
-
-/******************************************************************************
- * IMalloc32_DidAlloc [VTABLE]
- */
-static INT WINAPI IMalloc_fnDidAlloc(LPMALLOC iface,LPVOID pv) {
-	ICOM_CTHIS(IMalloc32Impl,iface);
-	TRACE("(%p)->DidAlloc(%p)\n",This,pv);
-	return -1;
-}
-
-/******************************************************************************
- * IMalloc32_HeapMinimize [VTABLE]
- */
-static VOID WINAPI IMalloc_fnHeapMinimize(LPMALLOC iface) {
-	ICOM_THIS(IMalloc32Impl,iface);
-	TRACE("(%p)->HeapMinimize()\n",This);
-}
-
-static ICOM_VTABLE(IMalloc) VT_IMalloc32 = 
-{
-    ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
-    IMalloc_fnQueryInterface,
-    IMalloc_fnAddRef,
-  IMalloc_fnRelease,
-  IMalloc_fnAlloc,
-  IMalloc_fnRealloc,
-  IMalloc_fnFree,
-  IMalloc_fnGetSize,
-  IMalloc_fnDidAlloc,
-  IMalloc_fnHeapMinimize
+{
+	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+	IMallocSpy_fnQueryInterface,
+	IMallocSpy_fnAddRef,
+	IMallocSpy_fnRelease,
+	IMallocSpy_fnPreAlloc,
+	IMallocSpy_fnPostAlloc,
+	IMallocSpy_fnPreFree,
+	IMallocSpy_fnPostFree,
+	IMallocSpy_fnPreRealloc,
+	IMallocSpy_fnPostRealloc,
+	IMallocSpy_fnPreGetSize,
+	IMallocSpy_fnPostGetSize,
+	IMallocSpy_fnPreDidAlloc,
+	IMallocSpy_fnPostDidAlloc,
+	IMallocSpy_fnPreHeapMinimize,
+	IMallocSpy_fnPostHeapMinimize
 };
 
 /******************************************************************************
- * IMalloc32_Constructor [VTABLE]
- */
-LPMALLOC
-IMalloc_Constructor() {
-	IMalloc32Impl* This;
-
-	This = (IMalloc32Impl*)HeapAlloc(GetProcessHeap(),0,sizeof(IMalloc32Impl));
-	ICOM_VTBL(This) = &VT_IMalloc32;
-	This->ref = 1;
-	return (LPMALLOC)This;
-}
-
-/****************************************************************************
- * API Functions
- */
+ *		CoGetMalloc	[OLE32.20]
+ *
+ * RETURNS
+ *	The win32 IMalloc
+ */
+HRESULT WINAPI CoGetMalloc(DWORD dwMemContext, LPMALLOC *lpMalloc)
+{
+        *lpMalloc = (LPMALLOC)&Malloc32;
+        return S_OK;
+}
+
+/***********************************************************************
+ *           CoTaskMemAlloc     [OLE32.43]
+ * RETURNS
+ * 	pointer to newly allocated block
+ */
+LPVOID WINAPI CoTaskMemAlloc(ULONG size)
+{
+        return IMalloc_Alloc((LPMALLOC)&Malloc32,size);
+}
+/***********************************************************************
+ *           CoTaskMemFree      [OLE32.44]
+ */
+VOID WINAPI CoTaskMemFree(LPVOID ptr)
+{
+        IMalloc_Free((LPMALLOC)&Malloc32, ptr);
+}
+
+/***********************************************************************
+ *           CoTaskMemRealloc   [OLE32.45]
+ * RETURNS
+ * 	pointer to newly allocated block
+ */
+LPVOID WINAPI CoTaskMemRealloc(LPVOID pvOld, ULONG size)
+{
+        return IMalloc_Realloc((LPMALLOC)&Malloc32, pvOld, size);
+}
+
+/***********************************************************************
+ *           CoRegisterMallocSpy        [OLE32.37]
+ *
+ * NOTES
+ *  if a mallocspy is already registered, we cant do it again since
+ *  only the spy knows, how to free a memory block
+ */
+HRESULT WINAPI CoRegisterMallocSpy(LPMALLOCSPY pMallocSpy)
+{
+	IMallocSpy* pSpy;
+        HRESULT hres = E_INVALIDARG;
+
+	TRACE("\n");
+
+	/* HACK TO ACTIVATE OUT SPY */
+	if (pMallocSpy == (LPVOID)-1) pMallocSpy =(IMallocSpy*)&MallocSpy;
+
+	if(Malloc32.pSpy) return CO_E_OBJISREG;
+
+        EnterCriticalSection(&IMalloc32_SpyCS);
+
+	if (SUCCEEDED(IUnknown_QueryInterface(pMallocSpy, &IID_IMallocSpy, (LPVOID*)&pSpy))) {
+	    Malloc32.pSpy = pSpy;
+	    hres = S_OK;
+	}
+
+	LeaveCriticalSection(&IMalloc32_SpyCS);
+
+	return hres;
+}
+
+/***********************************************************************
+ *           CoRevokeMallocSpy  [OLE32.41]
+ *
+ * NOTES
+ *  we can't rewoke a malloc spy as long as memory blocks allocated with
+ *  the spy are active since only the spy knows how to free them
+ */
+HRESULT WINAPI CoRevokeMallocSpy(void)
+{
+	HRESULT hres = S_OK;
+	TRACE("\n");
+
+        EnterCriticalSection(&IMalloc32_SpyCS);
+
+	/* if it's our spy it's time to dump the leaks */
+	if (Malloc32.pSpy == (IMallocSpy*)&MallocSpy) {
+	    MallocSpyDumpLeaks();
+	}
+
+	if (Malloc32.SpyedAllocationsLeft) {
+	    TRACE("SpyReleasePending with %lu allocations left\n", Malloc32.SpyedAllocationsLeft);
+	    Malloc32.SpyReleasePending = TRUE;
+	    hres = E_ACCESSDENIED;
+	} else {
+	    IMallocSpy_Release(Malloc32.pSpy);
+	    Malloc32.pSpy = NULL;
+        }
+	LeaveCriticalSection(&IMalloc32_SpyCS);
+
+	return S_OK;
+}
 
 /******************************************************************************
Index: trunk/src/ole32/itemmoniker.c
===================================================================
--- trunk/src/ole32/itemmoniker.c	(revision 9394)
+++ trunk/src/ole32/itemmoniker.c	(revision 9400)
@@ -388,5 +388,5 @@
     if (!This->itemName)
 	return E_OUTOFMEMORY;
-    strcpyW(This->itemName,lpszItem);
+    lstrcpyW(This->itemName,lpszItem);
 
     if (!lpszDelim)
@@ -395,5 +395,5 @@
     delim = lpszDelim ? lpszDelim : emptystr;
 
-    sizeStr2=strlenW(delim);
+    sizeStr2=lstrlenW(delim);
     This->itemDelimiter=HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*(sizeStr2+1));
     if (!This->itemDelimiter) {
@@ -401,5 +401,5 @@
 	return E_OUTOFMEMORY;
     }
-    strcpyW(This->itemDelimiter,delim);
+    lstrcpyW(This->itemDelimiter,delim);
     return S_OK;
 }
@@ -612,30 +612,26 @@
     LPOLESTR dispName1,dispName2;
     IBindCtx* bind;
-    HRESULT res;
+    HRESULT res = S_FALSE;
 
     TRACE("(%p,%p)\n",iface,pmkOtherMoniker);
 
-    if (pmkOtherMoniker==NULL)
-        return S_FALSE;
-
-    /* This method returns S_OK if both monikers are item monikers and their display names are */
-    /* identical (using a case-insensitive comparison); otherwise, the method returns S_FALSE. */
-
-    IMoniker_GetClassID(pmkOtherMoniker,&clsid);
-
-    if (!IsEqualCLSID(&clsid,&CLSID_ItemMoniker))
-        return S_FALSE;
-
-    res=CreateBindCtx(0,&bind);
-    if (FAILED(res))
-        return res;
-
-    IMoniker_GetDisplayName(iface,bind,NULL,&dispName1);
-    IMoniker_GetDisplayName(pmkOtherMoniker,bind,NULL,&dispName2);
-
-    if (lstrcmpW(dispName1,dispName2)!=0)
-        return S_FALSE;
-
-    return S_OK;
+    if (!pmkOtherMoniker) return S_FALSE;
+
+
+    /* check if both are ItemMoniker */
+    if(FAILED (IMoniker_GetClassID(pmkOtherMoniker,&clsid))) return S_FALSE;
+    if(!IsEqualCLSID(&clsid,&CLSID_ItemMoniker)) return S_FALSE;
+
+    /* check if both displaynames are the same */
+    if(SUCCEEDED ((res = CreateBindCtx(0,&bind)))) {
+        if(SUCCEEDED (IMoniker_GetDisplayName(iface,bind,NULL,&dispName1))) {
+	    if(SUCCEEDED (IMoniker_GetDisplayName(pmkOtherMoniker,bind,NULL,&dispName2))) {
+                if(lstrcmpW(dispName1,dispName2)==0) res = S_OK;
+                CoTaskMemFree(dispName2);
+            }
+            CoTaskMemFree(dispName1);
+	}
+    }
+    return res;
 }
 
@@ -843,6 +839,6 @@
         return E_OUTOFMEMORY;
 
-    strcpyW(*ppszDisplayName,This->itemDelimiter);
-    strcatW(*ppszDisplayName,This->itemName);
+    lstrcpyW(*ppszDisplayName,This->itemDelimiter);
+    lstrcatW(*ppszDisplayName,This->itemName);
 
     return S_OK;
Index: trunk/src/ole32/marshal.c
===================================================================
--- trunk/src/ole32/marshal.c	(revision 9394)
+++ trunk/src/ole32/marshal.c	(revision 9400)
@@ -317,10 +317,12 @@
   }
   hres = PIPE_GetNewPipeBuf(&mid,&chanbuf);
-  if (hres)
-    FIXME("Failed to get an rpc channel buffer for %s\n",debugstr_guid(riid));
-  IRpcProxyBuffer_Connect(rpcproxy,chanbuf);
-  IRpcProxyBuffer_Release(rpcproxy); /* no need */
+  if (hres) {
+    ERR("Failed to get an rpc channel buffer for %s\n",debugstr_guid(riid));
+  } else {
+    IRpcProxyBuffer_Connect(rpcproxy,chanbuf);
+    IRpcProxyBuffer_Release(rpcproxy); /* no need */
+  }
   IPSFactoryBuffer_Release(psfacbuf);
-  return S_OK;
+  return hres;
 }
 
@@ -483,5 +485,9 @@
 	MESSAGE("       Wine registry by running: `regedit winedefault.reg'\n\n");
     } else {
-	FIXME("Failed to Marshal the interface, %lx?\n",hres);
+    	if (IsEqualGUID(riid,&IID_IOleObject)) {
+	    ERR("WINE currently cannot marshal IOleObject interfaces. This means you cannot embed/link OLE objects between applications.\n");
+	} else {
+	    FIXME("Failed to marshal the interface %s, %lx?\n",debugstr_guid(riid),hres);
+	}
     }
     goto release_marshal;
Index: trunk/src/ole32/ole2stubs.c
===================================================================
--- trunk/src/ole32/ole2stubs.c	(revision 9394)
+++ trunk/src/ole32/ole2stubs.c	(revision 9400)
@@ -98,5 +98,5 @@
   FIXME("\n\t%s\n\t%s stub!\n", debugstr_guid(rclsid), debugstr_guid(riid));
 
-  if (SUCCEEDED((hres = CoCreateInstance(rclsid, 0, CLSCTX_INPROC_SERVER, riid, (LPVOID*)&pUnk))))
+  if (SUCCEEDED((hres = CoCreateInstance(rclsid, 0, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER|CLSCTX_LOCAL_SERVER , riid, (LPVOID*)&pUnk))))
   {
     if (pClientSite)
Index: trunk/src/ole32/ole32.c
===================================================================
--- trunk/src/ole32/ole32.c	(revision 9400)
+++ trunk/src/ole32/ole32.c	(revision 9400)
@@ -0,0 +1,106 @@
+/* $Id: ole32.c,v 1.1 2002-11-12 17:06:30 sandervl Exp $ */
+/* 
+ * 
+ * Project Odin Software License can be found in LICENSE.TXT
+ * 
+ */
+/* 
+ * COM/OLE misc. functions.
+ * 
+ * 1/7/99
+ * 
+ * Copyright 1999 David J. Raison
+ * 
+ * Some portions from Wine Implementation
+ *   Copyright 1995  Martin von Loewis
+ *   Copyright 1998  Justin Bradford
+ *   Copyright 1999  Francis Beaudet
+ *   Copyright 1999  Sylvain St-Germain
+ */
+
+#include "ole32.h"
+#include "compobj_private.h"
+
+// ----------------------------------------------------------------------
+// CoDosDateTimeToFileTime
+// ----------------------------------------------------------------------
+BOOL WIN32API CoDosDateTimeToFileTime(WORD nDosDate, WORD nDosTime,
+                                         FILETIME *lpFileTime)
+{
+    dprintf(("OLE32: CoDosDateTimeToFileTime"));
+
+    return DosDateTimeToFileTime(nDosDate, nDosTime, lpFileTime);
+}
+
+// ----------------------------------------------------------------------
+// CoDosDateTimeToFileTime
+// ----------------------------------------------------------------------
+BOOL WIN32API CoFileTimeToDosDateTime(FILETIME *lpFileTime, LPWORD lpDosDate,
+                                         LPWORD lpDosTime)
+{
+    dprintf(("OLE32: CoFileTimeToDosDateTime"));
+
+    return FileTimeToDosDateTime(lpFileTime, lpDosDate, lpDosTime);
+}
+
+// ----------------------------------------------------------------------
+// CLSIDFromStringA()
+// @@@PH: this is not a WINE API, but a replacement for CLSIDFromString16
+//        which used to accept ASCII strings instead of OLE strings
+// ----------------------------------------------------------------------
+
+HRESULT WIN32API CLSIDFromStringA(
+    LPCSTR		lpsz,		// [in] - ASCII string CLSID
+    LPCLSID		pclsid)		// [out] - Binary CLSID
+{
+    return CLSIDFromString16(lpsz, pclsid);
+}
+
+/******************************************************************************
+ *		CLSIDFromProgID	[COMPOBJ.61]
+ * Converts a program id into the respective GUID. (By using a registry lookup)
+ * RETURNS
+ *	riid associated with the progid
+ */
+HRESULT WINAPI CLSIDFromProgID16(
+	LPCOLESTR16 progid,	/* [in] program id as found in registry */
+	LPCLSID riid		/* [out] associated CLSID */
+) {
+	char	*buf,buf2[80];
+	DWORD	buf2len;
+	HRESULT	err;
+	HKEY	xhkey;
+
+	buf = HeapAlloc(GetProcessHeap(),0,strlen(progid)+8);
+	sprintf(buf,"%s\\CLSID",progid);
+	if ((err=RegOpenKeyA(HKEY_CLASSES_ROOT,buf,&xhkey))) {
+		HeapFree(GetProcessHeap(),0,buf);
+                return CO_E_CLASSSTRING;
+	}
+	HeapFree(GetProcessHeap(),0,buf);
+	buf2len = sizeof(buf2);
+	if ((err=RegQueryValueA(xhkey,NULL,buf2,&buf2len))) {
+		RegCloseKey(xhkey);
+                return CO_E_CLASSSTRING;
+	}
+	RegCloseKey(xhkey);
+	return __CLSIDFromStringA(buf2,riid);
+}
+
+/******************************************************************************
+ *		CLSIDFromString	[COMPOBJ.20]
+ * Converts a unique identifier from its string representation into
+ * the GUID struct.
+ *
+ * Class id: DWORD-WORD-WORD-BYTES[2]-BYTES[6]
+ *
+ * RETURNS
+ *	the converted GUID
+ */
+HRESULT WINAPI CLSIDFromString16(
+	LPCOLESTR16 idstr,	/* [in] string representation of guid */
+	CLSID *id)		/* [out] GUID converted from string */
+{
+
+  return __CLSIDFromStringA(idstr,id);
+}
Index: trunk/src/ole32/ole32.cpp
===================================================================
--- trunk/src/ole32/ole32.cpp	(revision 9394)
+++ 	(revision )
@@ -1,56 +1,0 @@
-/* $Id: ole32.cpp,v 1.16 2002-02-15 17:18:50 sandervl Exp $ */
-/* 
- * 
- * Project Odin Software License can be found in LICENSE.TXT
- * 
- */
-/* 
- * COM/OLE misc. functions.
- * 
- * 1/7/99
- * 
- * Copyright 1999 David J. Raison
- * 
- * Some portions from Wine Implementation
- *   Copyright 1995  Martin von Loewis
- *   Copyright 1998  Justin Bradford
- *   Copyright 1999  Francis Beaudet
- *   Copyright 1999  Sylvain St-Germain
- */
-
-#include "ole32.h"
-
-// ----------------------------------------------------------------------
-// CoDosDateTimeToFileTime
-// ----------------------------------------------------------------------
-BOOL WIN32API CoDosDateTimeToFileTime(WORD nDosDate, WORD nDosTime,
-                                         FILETIME *lpFileTime)
-{
-    dprintf(("OLE32: CoDosDateTimeToFileTime"));
-
-    return DosDateTimeToFileTime(nDosDate, nDosTime, lpFileTime);
-}
-
-// ----------------------------------------------------------------------
-// CoDosDateTimeToFileTime
-// ----------------------------------------------------------------------
-BOOL WIN32API CoFileTimeToDosDateTime(FILETIME *lpFileTime, LPWORD lpDosDate,
-                                         LPWORD lpDosTime)
-{
-    dprintf(("OLE32: CoFileTimeToDosDateTime"));
-
-    return FileTimeToDosDateTime(lpFileTime, lpDosDate, lpDosTime);
-}
-
-// ----------------------------------------------------------------------
-// CLSIDFromStringA()
-// @@@PH: this is not a WINE API, but a replacement for CLSIDFromString16
-//        which used to accept ASCII strings instead of OLE strings
-// ----------------------------------------------------------------------
-
-HRESULT WIN32API CLSIDFromStringA(
-    LPCSTR		lpsz,		// [in] - ASCII string CLSID
-    LPCLSID		pclsid)		// [out] - Binary CLSID
-{
-    return CLSIDFromString16(lpsz, pclsid);
-}
Index: trunk/src/ole32/ole32.def
===================================================================
--- trunk/src/ole32/ole32.def	(revision 9394)
+++ trunk/src/ole32/ole32.def	(revision 9400)
@@ -168,5 +168,5 @@
     WriteStringStream          = _WriteStringStream@0        @162
     CoInitializeEx             = _CoInitializeEx@8           @163
-;164 stub CoInitializeSecurity       # stdcall (ptr long ptr ptr long long ptr long ptr) return 0,ERR_NOTIMPLEMENTED
+    CoInitializeSecurity       = _CoInitializeSecurity@36    @164
     CoCreateInstanceEx         = _CoCreateInstanceEx@24      @165
     PropVariantClear           = _PropVariantClear@4         @166
Index: trunk/src/ole32/ole32.mak
===================================================================
--- trunk/src/ole32/ole32.mak	(revision 9394)
+++ trunk/src/ole32/ole32.mak	(revision 9400)
@@ -1,3 +1,3 @@
-# $Id: ole32.mak,v 1.20 2002-05-16 19:26:29 sandervl Exp $
+# $Id: ole32.mak,v 1.21 2002-11-12 17:06:02 sandervl Exp $
 
 #
@@ -39,8 +39,10 @@
 $(OBJDIR)\bindctx.obj \
 $(OBJDIR)\compositemoniker.obj \
+$(OBJDIR)\compobj.obj \
 $(OBJDIR)\datacache.obj \
 $(OBJDIR)\defaulthandler.obj \
 $(OBJDIR)\errorinfo.obj \
 $(OBJDIR)\filemoniker.obj \
+$(OBJDIR)\ftmarshal.obj \
 $(OBJDIR)\hglobalstream.obj \
 $(OBJDIR)\initialise.obj \
@@ -52,5 +54,4 @@
 $(OBJDIR)\ole2.obj \
 $(OBJDIR)\oleobj.obj \
-$(OBJDIR)\compobj.obj \
 $(OBJDIR)\clipboard.obj \
 $(OBJDIR)\ole2stubs.obj \
Index: trunk/src/ole32/ole32dbg.def
===================================================================
--- trunk/src/ole32/ole32dbg.def	(revision 9394)
+++ trunk/src/ole32/ole32dbg.def	(revision 9400)
@@ -169,5 +169,5 @@
 
     CoInitializeEx             = _DbgCoInitializeEx@8           @163
-;164 stub CoInitializeSecurity       # stdcall (ptr long ptr ptr long long ptr long ptr) return 0,ERR_NOTIMPLEMENTED
+    CoInitializeSecurity       = _DbgCoInitializeSecurity@36    @164
     CoCreateInstanceEx         = _DbgCoCreateInstanceEx@24      @165
     PropVariantClear           = _DbgPropVariantClear@4         @166
Index: trunk/src/ole32/stg_stream.c
===================================================================
--- trunk/src/ole32/stg_stream.c	(revision 9394)
+++ trunk/src/ole32/stg_stream.c	(revision 9400)
@@ -30,5 +30,5 @@
 #include "winbase.h"
 #include "winerror.h"
-#include "ntddk.h"
+#include "winternl.h"
 #include "wine/debug.h"
 
@@ -565,5 +565,4 @@
   plibNewPosition->QuadPart = RtlLargeIntegerAdd( plibNewPosition->QuadPart, dlibMove.QuadPart );
 #endif
-
   /*
    * tell the caller what we calculated
Index: trunk/src/ole32/storage32.c
===================================================================
--- trunk/src/ole32/storage32.c	(revision 9394)
+++ trunk/src/ole32/storage32.c	(revision 9400)
@@ -2321,11 +2321,12 @@
    * Create the block chain abstractions.
    */
-  This->rootBlockChain =
-    BlockChainStream_Construct(This, &This->rootStartBlock, PROPERTY_NULL);
-
-  This->smallBlockDepotChain = BlockChainStream_Construct(
-                                 This,
-                                 &This->smallBlockDepotStart,
-                                 PROPERTY_NULL);
+  if(!(This->rootBlockChain =
+       BlockChainStream_Construct(This, &This->rootStartBlock, PROPERTY_NULL)))
+    return STG_E_READFAULT;
+
+  if(!(This->smallBlockDepotChain =
+       BlockChainStream_Construct(This, &This->smallBlockDepotStart,
+				  PROPERTY_NULL)))
+    return STG_E_READFAULT;
 
   /*
@@ -2381,5 +2382,5 @@
   {
     /* TODO CLEANUP */
-    return E_FAIL;
+    return STG_E_READFAULT;
   }
 
@@ -2387,8 +2388,7 @@
    * Create the block chain abstraction for the small block root chain.
    */
-  This->smallBlockRootChain = BlockChainStream_Construct(
-                                This,
-                                NULL,
-                                This->rootPropertySetIndex);
+  if(!(This->smallBlockRootChain =
+       BlockChainStream_Construct(This, NULL, This->rootPropertySetIndex)))
+    return STG_E_READFAULT;
 
   return hr;
@@ -2731,4 +2731,5 @@
  *          blockIndex - Index of the block to retrieve the chain
  *                       for.
+ *          nextBlockIndex - receives the return value.
  *
  * Returns: This method returns the index of the next block in the chain.
@@ -2745,16 +2746,24 @@
  * See Windows documentation for more details on IStorage methods.
  */
-ULONG StorageImpl_GetNextBlockInChain(
+HRESULT StorageImpl_GetNextBlockInChain(
   StorageImpl* This,
-  ULONG          blockIndex)
+  ULONG        blockIndex,
+  ULONG*       nextBlockIndex)
 {
   ULONG offsetInDepot    = blockIndex * sizeof (ULONG);
   ULONG depotBlockCount  = offsetInDepot / This->bigBlockSize;
   ULONG depotBlockOffset = offsetInDepot % This->bigBlockSize;
-  ULONG nextBlockIndex   = BLOCK_SPECIAL;
   void* depotBuffer;
   ULONG depotBlockIndexPos;
-
-  assert(depotBlockCount < This->bigBlockDepotCount);
+  int index;
+
+  *nextBlockIndex   = BLOCK_SPECIAL;
+
+  if(depotBlockCount >= This->bigBlockDepotCount)
+  {
+    WARN("depotBlockCount %ld, bigBlockDepotCount %ld\n", depotBlockCount,
+	 This->bigBlockDepotCount);
+    return STG_E_READFAULT;
+  }
 
   /*
@@ -2779,21 +2788,18 @@
     depotBuffer = StorageImpl_GetROBigBlock(This, depotBlockIndexPos);
 
-    if (depotBuffer!=0)
-    {
-      int index;
-
-      for (index = 0; index < NUM_BLOCKS_PER_DEPOT_BLOCK; index++)
-      {
-        StorageUtl_ReadDWord(depotBuffer, index*sizeof(ULONG), &nextBlockIndex);
-        This->blockDepotCached[index] = nextBlockIndex;
-      }
-
-      StorageImpl_ReleaseBigBlock(This, depotBuffer);
-    }
-  }
-
-  nextBlockIndex = This->blockDepotCached[depotBlockOffset/sizeof(ULONG)];
-
-  return nextBlockIndex;
+    if (!depotBuffer)
+      return STG_E_READFAULT;
+
+    for (index = 0; index < NUM_BLOCKS_PER_DEPOT_BLOCK; index++)
+    {
+      StorageUtl_ReadDWord(depotBuffer, index*sizeof(ULONG), nextBlockIndex);
+      This->blockDepotCached[index] = *nextBlockIndex;
+    }
+    StorageImpl_ReleaseBigBlock(This, depotBuffer);
+  }
+
+  *nextBlockIndex = This->blockDepotCached[depotBlockOffset/sizeof(ULONG)];
+
+  return S_OK;
 }
 
@@ -3044,5 +3050,4 @@
     StorageUtl_WriteWord(headerBigBlock,  0x1c, (WORD)-2);
     StorageUtl_WriteDWord(headerBigBlock, 0x38, (DWORD)0x1000);
-    StorageUtl_WriteDWord(headerBigBlock, 0x40, (DWORD)0x0001);
   }
 
@@ -3050,48 +3055,51 @@
    * Write the information to the header.
    */
-  if (headerBigBlock!=0)
-  {
-    StorageUtl_WriteWord(
-      headerBigBlock,
-      OFFSET_BIGBLOCKSIZEBITS,
-      This->bigBlockSizeBits);
-
-    StorageUtl_WriteWord(
-      headerBigBlock,
-      OFFSET_SMALLBLOCKSIZEBITS,
-      This->smallBlockSizeBits);
-
+  StorageUtl_WriteWord(
+    headerBigBlock,
+    OFFSET_BIGBLOCKSIZEBITS,
+    This->bigBlockSizeBits);
+
+  StorageUtl_WriteWord(
+    headerBigBlock,
+    OFFSET_SMALLBLOCKSIZEBITS,
+    This->smallBlockSizeBits);
+
+  StorageUtl_WriteDWord(
+    headerBigBlock,
+    OFFSET_BBDEPOTCOUNT,
+    This->bigBlockDepotCount);
+
+  StorageUtl_WriteDWord(
+    headerBigBlock,
+    OFFSET_ROOTSTARTBLOCK,
+    This->rootStartBlock);
+
+  StorageUtl_WriteDWord(
+    headerBigBlock,
+    OFFSET_SBDEPOTSTART,
+    This->smallBlockDepotStart);
+
+  StorageUtl_WriteDWord(
+    headerBigBlock,
+    OFFSET_SBDEPOTCOUNT,
+    This->smallBlockDepotChain ?
+     BlockChainStream_GetCount(This->smallBlockDepotChain) : 0);
+
+  StorageUtl_WriteDWord(
+    headerBigBlock,
+    OFFSET_EXTBBDEPOTSTART,
+    This->extBigBlockDepotStart);
+
+  StorageUtl_WriteDWord(
+    headerBigBlock,
+    OFFSET_EXTBBDEPOTCOUNT,
+    This->extBigBlockDepotCount);
+
+  for (index = 0; index < COUNT_BBDEPOTINHEADER; index ++)
+  {
     StorageUtl_WriteDWord(
       headerBigBlock,
-      OFFSET_BBDEPOTCOUNT,
-      This->bigBlockDepotCount);
-
-    StorageUtl_WriteDWord(
-      headerBigBlock,
-      OFFSET_ROOTSTARTBLOCK,
-      This->rootStartBlock);
-
-    StorageUtl_WriteDWord(
-      headerBigBlock,
-      OFFSET_SBDEPOTSTART,
-      This->smallBlockDepotStart);
-
-    StorageUtl_WriteDWord(
-      headerBigBlock,
-      OFFSET_EXTBBDEPOTSTART,
-      This->extBigBlockDepotStart);
-
-    StorageUtl_WriteDWord(
-      headerBigBlock,
-      OFFSET_EXTBBDEPOTCOUNT,
-      This->extBigBlockDepotCount);
-
-    for (index = 0; index < COUNT_BBDEPOTINHEADER; index ++)
-    {
-      StorageUtl_WriteDWord(
-        headerBigBlock,
-        OFFSET_BBDEPOTSTART + (sizeof(ULONG)*index),
-        (This->bigBlockDepotStart[index]));
-    }
+      OFFSET_BBDEPOTSTART + (sizeof(ULONG)*index),
+      (This->bigBlockDepotStart[index]));
   }
 
@@ -3382,5 +3390,5 @@
                                            &bbHeadOfChain,
                                            PROPERTY_NULL);
-
+  if(!bbTempChain) return NULL;
   /*
    * Grow the big block chain.
@@ -4163,7 +4171,12 @@
     newStream->tailIndex = blockIndex;
 
-    blockIndex = StorageImpl_GetNextBlockInChain(
-                   parentStorage,
-                   blockIndex);
+    if(FAILED(StorageImpl_GetNextBlockInChain(
+	      parentStorage,
+	      blockIndex,
+	      &blockIndex)))
+    {
+      HeapFree(GetProcessHeap(), 0, newStream);
+      return NULL;
+    }
   }
 
@@ -4226,7 +4239,9 @@
     count++;
 
-    blockIndex = StorageImpl_GetNextBlockInChain(
+    if(FAILED(StorageImpl_GetNextBlockInChain(
                    This->parentStorage,
-                   blockIndex);
+                   blockIndex,
+		   &blockIndex)))
+      return 0;
   }
 
@@ -4275,7 +4290,6 @@
   while ( (blockNoInSequence > 0) &&  (blockIndex != BLOCK_END_OF_CHAIN))
   {
-    blockIndex =
-      StorageImpl_GetNextBlockInChain(This->parentStorage, blockIndex);
-
+    if(FAILED(StorageImpl_GetNextBlockInChain(This->parentStorage, blockIndex, &blockIndex)))
+      return FALSE;
     blockNoInSequence--;
   }
@@ -4310,6 +4324,6 @@
      * Step to the next big block.
      */
-    blockIndex    =
-      StorageImpl_GetNextBlockInChain(This->parentStorage, blockIndex);
+    if(FAILED(StorageImpl_GetNextBlockInChain(This->parentStorage, blockIndex, &blockIndex)))
+      return FALSE;
 
     bufferWalker += bytesToReadInBuffer;
@@ -4364,7 +4378,7 @@
   while ( (blockNoInSequence > 0) &&  (blockIndex != BLOCK_END_OF_CHAIN))
   {
-    blockIndex =
-      StorageImpl_GetNextBlockInChain(This->parentStorage, blockIndex);
-
+    if(FAILED(StorageImpl_GetNextBlockInChain(This->parentStorage, blockIndex,
+					      &blockIndex)))
+      return FALSE;
     blockNoInSequence--;
   }
@@ -4399,7 +4413,7 @@
      * Step to the next big block.
      */
-    blockIndex    =
-      StorageImpl_GetNextBlockInChain(This->parentStorage, blockIndex);
-
+    if(FAILED(StorageImpl_GetNextBlockInChain(This->parentStorage, blockIndex,
+					      &blockIndex)))
+      return FALSE;
     bufferWalker  += bytesToWrite;
     size          -= bytesToWrite;
@@ -4444,13 +4458,14 @@
   while (count < numBlocks)
   {
-    blockIndex =
-      StorageImpl_GetNextBlockInChain(This->parentStorage, blockIndex);
-
+    if(FAILED(StorageImpl_GetNextBlockInChain(This->parentStorage, blockIndex,
+					      &blockIndex)))
+      return FALSE;
     count++;
   }
 
   /* Get the next block before marking the new end */
-  extraBlock =
-    StorageImpl_GetNextBlockInChain(This->parentStorage, blockIndex);
+  if(FAILED(StorageImpl_GetNextBlockInChain(This->parentStorage, blockIndex,
+					    &extraBlock)))
+    return FALSE;
 
   /* Mark the new end of chain */
@@ -4468,7 +4483,7 @@
   while (extraBlock != BLOCK_END_OF_CHAIN)
   {
-    blockIndex =
-      StorageImpl_GetNextBlockInChain(This->parentStorage, extraBlock);
-
+    if(FAILED(StorageImpl_GetNextBlockInChain(This->parentStorage, extraBlock,
+					      &blockIndex)))
+      return FALSE;
     StorageImpl_FreeBigBlock(This->parentStorage, extraBlock);
     extraBlock = blockIndex;
@@ -4548,6 +4563,7 @@
       currentBlock = blockIndex;
 
-      blockIndex =
-        StorageImpl_GetNextBlockInChain(This->parentStorage, currentBlock);
+      if(FAILED(StorageImpl_GetNextBlockInChain(This->parentStorage, currentBlock,
+						&blockIndex)))
+	return FALSE;
     }
 
@@ -4736,13 +4752,15 @@
  *    - BLOCK_UNUSED: small block 'blockIndex' is free
  */
-ULONG SmallBlockChainStream_GetNextBlockInChain(
+HRESULT SmallBlockChainStream_GetNextBlockInChain(
   SmallBlockChainStream* This,
-  ULONG                  blockIndex)
+  ULONG                  blockIndex,
+  ULONG*                 nextBlockInChain)
 {
   ULARGE_INTEGER offsetOfBlockInDepot;
   DWORD  buffer;
-  ULONG  nextBlockInChain = BLOCK_END_OF_CHAIN;
   ULONG  bytesRead;
   BOOL success;
+
+  *nextBlockInChain = BLOCK_END_OF_CHAIN;
 
   offsetOfBlockInDepot.s.HighPart = 0;
@@ -4761,8 +4779,9 @@
   if (success)
   {
-    StorageUtl_ReadDWord(&buffer, 0, &nextBlockInChain);
-  }
-
-  return nextBlockInChain;
+    StorageUtl_ReadDWord(&buffer, 0, nextBlockInChain);
+    return S_OK;
+  }
+
+  return STG_E_READFAULT;
 }
 
@@ -4869,6 +4888,5 @@
       {
         sbdIndex = nextBlock;
-        nextBlock =
-          StorageImpl_GetNextBlockInChain(This->parentStorage, sbdIndex);
+	StorageImpl_GetNextBlockInChain(This->parentStorage, sbdIndex, &nextBlock);
       }
 
@@ -5007,6 +5025,7 @@
   while ( (blockNoInSequence > 0) &&  (blockIndex != BLOCK_END_OF_CHAIN))
   {
-    blockIndex = SmallBlockChainStream_GetNextBlockInChain(This, blockIndex);
-
+    if(FAILED(SmallBlockChainStream_GetNextBlockInChain(This, blockIndex,
+							&blockIndex)))
+      return FALSE;
     blockNoInSequence--;
   }
@@ -5049,5 +5068,6 @@
      * Step to the next big block.
      */
-    blockIndex    = SmallBlockChainStream_GetNextBlockInChain(This, blockIndex);
+    if(FAILED(SmallBlockChainStream_GetNextBlockInChain(This, blockIndex, &blockIndex)))
+      return FALSE;
     bufferWalker += bytesToReadInBuffer;
     size         -= bytesToReadInBuffer;
@@ -5095,6 +5115,6 @@
   while ( (blockNoInSequence > 0) &&  (blockIndex != BLOCK_END_OF_CHAIN))
   {
-    blockIndex = SmallBlockChainStream_GetNextBlockInChain(This, blockIndex);
-
+    if(FAILED(SmallBlockChainStream_GetNextBlockInChain(This, blockIndex, &blockIndex)))
+      return FALSE;
     blockNoInSequence--;
   }
@@ -5139,5 +5159,7 @@
      * Step to the next big block.
      */
-    blockIndex    = SmallBlockChainStream_GetNextBlockInChain(This, blockIndex);
+    if(FAILED(SmallBlockChainStream_GetNextBlockInChain(This, blockIndex,
+							&blockIndex)))
+      return FALSE;
     bufferWalker  += bytesToWriteInBuffer;
     size          -= bytesToWriteInBuffer;
@@ -5174,5 +5196,7 @@
   while (count < numBlocks)
   {
-    blockIndex = SmallBlockChainStream_GetNextBlockInChain(This, blockIndex);
+    if(FAILED(SmallBlockChainStream_GetNextBlockInChain(This, blockIndex,
+							&blockIndex)))
+      return FALSE;
     count++;
   }
@@ -5204,5 +5228,7 @@
   {
     /* Get the next block before marking the new end */
-    extraBlock = SmallBlockChainStream_GetNextBlockInChain(This, blockIndex);
+    if(FAILED(SmallBlockChainStream_GetNextBlockInChain(This, blockIndex,
+							&extraBlock)))
+      return FALSE;
 
     /* Mark the new end of chain */
@@ -5218,5 +5244,7 @@
   while (extraBlock != BLOCK_END_OF_CHAIN)
   {
-    blockIndex = SmallBlockChainStream_GetNextBlockInChain(This, extraBlock);
+    if(FAILED(SmallBlockChainStream_GetNextBlockInChain(This, extraBlock,
+							&blockIndex)))
+      return FALSE;
     SmallBlockChainStream_FreeBlock(This, extraBlock);
     extraBlock = blockIndex;
@@ -5281,5 +5309,6 @@
     oldNumBlocks++;
     currentBlock = blockIndex;
-    blockIndex = SmallBlockChainStream_GetNextBlockInChain(This, currentBlock);
+    if(FAILED(SmallBlockChainStream_GetNextBlockInChain(This, currentBlock, &blockIndex)))
+      return FALSE;
   }
 
@@ -5321,5 +5350,6 @@
     count++;
 
-    blockIndex = SmallBlockChainStream_GetNextBlockInChain(This, blockIndex);
+    if(FAILED(SmallBlockChainStream_GetNextBlockInChain(This, blockIndex, &blockIndex)))
+      return 0;
   }
 
@@ -5744,5 +5774,5 @@
          newStorage,
          0,
-        0,
+         0,
          plkbyt,
          grfMode,
Index: trunk/src/ole32/storage32.h
===================================================================
--- trunk/src/ole32/storage32.h	(revision 9394)
+++ trunk/src/ole32/storage32.h	(revision 9400)
@@ -7,5 +7,5 @@
  *
  * This include file contains definitions of types and function
- * prototypes that are used in the many files implementing the 
+ * prototypes that are used in the many files implementing the
  * storage functionality
  *
@@ -43,4 +43,5 @@
 static const ULONG OFFSET_ROOTSTARTBLOCK     = 0x00000030;
 static const ULONG OFFSET_SBDEPOTSTART	     = 0x0000003C;
+static const ULONG OFFSET_SBDEPOTCOUNT       = 0x00000040;
 static const ULONG OFFSET_EXTBBDEPOTSTART    = 0x00000044;
 static const ULONG OFFSET_EXTBBDEPOTCOUNT    = 0x00000048;
@@ -50,5 +51,5 @@
 static const ULONG OFFSET_PS_PROPERTYTYPE    = 0x00000042;
 static const ULONG OFFSET_PS_PREVIOUSPROP    = 0x00000044;
-static const ULONG OFFSET_PS_NEXTPROP        = 0x00000048;   
+static const ULONG OFFSET_PS_NEXTPROP        = 0x00000048;
 static const ULONG OFFSET_PS_DIRPROP	     = 0x0000004C;
 static const ULONG OFFSET_PS_GUID            = 0x00000050;
@@ -57,6 +58,6 @@
 static const ULONG OFFSET_PS_TSS2            = 0x0000006C;
 static const ULONG OFFSET_PS_TSD2            = 0x00000070;
-static const ULONG OFFSET_PS_STARTBLOCK	     = 0x00000074; 
-static const ULONG OFFSET_PS_SIZE	     = 0x00000078; 
+static const ULONG OFFSET_PS_STARTBLOCK	     = 0x00000074;
+static const ULONG OFFSET_PS_SIZE	     = 0x00000078;
 static const WORD  DEF_BIG_BLOCK_SIZE_BITS   = 0x0009;
 static const WORD  DEF_SMALL_BLOCK_SIZE_BITS = 0x0006;
@@ -70,5 +71,5 @@
 
 #define PROPERTY_NAME_MAX_LEN    0x20
-#define PROPERTY_NAME_BUFFER_LEN 0x40             
+#define PROPERTY_NAME_BUFFER_LEN 0x40
 
 #define PROPSET_BLOCK_SIZE 0x00000080
@@ -142,5 +143,5 @@
  *
  * The big block file is an abstraction of a flat file separated in
- * same sized blocks. The implementation for the methods described in 
+ * same sized blocks. The implementation for the methods described in
  * this section appear in stg_bigblockfile.c
  */
@@ -209,10 +210,10 @@
    */
   ULONG ref;
-  
-  /* 
-   * Ancestor storage (top level) 
-   */
-  StorageImpl* ancestorStorage;		 
-  
+
+  /*
+   * Ancestor storage (top level)
+   */
+  StorageImpl* ancestorStorage;
+
   /*
    * Index of the property for the root of
@@ -220,6 +221,6 @@
    */
   ULONG rootPropertySetIndex;
-  
-  /* 
+
+  /*
    * virtual Destructor method.
    */
@@ -235,39 +236,39 @@
             REFIID             riid,
             void**             ppvObject);
-        
-ULONG WINAPI StorageBaseImpl_AddRef( 
+
+ULONG WINAPI StorageBaseImpl_AddRef(
             IStorage*        iface);
-        
-ULONG WINAPI StorageBaseImpl_Release( 
+
+ULONG WINAPI StorageBaseImpl_Release(
             IStorage*        iface);
-        
-HRESULT WINAPI StorageBaseImpl_OpenStream( 
+
+HRESULT WINAPI StorageBaseImpl_OpenStream(
             IStorage*        iface,
             const OLECHAR*   pwcsName,  /* [string][in] */
             void*              reserved1, /* [unique][in] */
-            DWORD              grfMode,   /* [in] */        
-            DWORD              reserved2, /* [in] */        
-            IStream**        ppstm);    /* [out] */   
-    
-HRESULT WINAPI StorageBaseImpl_OpenStorage( 
+            DWORD              grfMode,   /* [in] */
+            DWORD              reserved2, /* [in] */
+            IStream**        ppstm);    /* [out] */
+
+HRESULT WINAPI StorageBaseImpl_OpenStorage(
             IStorage*        iface,
-            const OLECHAR*   pwcsName,      /* [string][unique][in] */ 
-            IStorage*        pstgPriority,  /* [unique][in] */         
-            DWORD              grfMode,       /* [in] */                 
-            SNB              snbExclude,    /* [unique][in] */         
-            DWORD              reserved,      /* [in] */                 
-            IStorage**       ppstg);        /* [out] */                
-          
-HRESULT WINAPI StorageBaseImpl_EnumElements( 
+            const OLECHAR*   pwcsName,      /* [string][unique][in] */
+            IStorage*        pstgPriority,  /* [unique][in] */
+            DWORD              grfMode,       /* [in] */
+            SNB              snbExclude,    /* [unique][in] */
+            DWORD              reserved,      /* [in] */
+            IStorage**       ppstg);        /* [out] */
+
+HRESULT WINAPI StorageBaseImpl_EnumElements(
             IStorage*        iface,
-            DWORD              reserved1, /* [in] */                  
-            void*              reserved2, /* [size_is][unique][in] */ 
-            DWORD              reserved3, /* [in] */                  
-            IEnumSTATSTG**     ppenum);   /* [out] */   
-
-HRESULT WINAPI StorageBaseImpl_Stat( 
+            DWORD              reserved1, /* [in] */
+            void*              reserved2, /* [size_is][unique][in] */
+            DWORD              reserved3, /* [in] */
+            IEnumSTATSTG**     ppenum);   /* [out] */
+
+HRESULT WINAPI StorageBaseImpl_Stat(
             IStorage*        iface,
-            STATSTG*           pstatstg,     /* [out] */ 
-            DWORD              grfStatFlag); /* [in] */  
+            STATSTG*           pstatstg,     /* [out] */
+            DWORD              grfStatFlag); /* [in] */
 
 HRESULT WINAPI StorageBaseImpl_RenameElement(
@@ -304,8 +305,8 @@
    */
   ULONG		        ref;
-  struct StorageImpl* ancestorStorage;		 
+  struct StorageImpl* ancestorStorage;
   ULONG                 rootPropertySetIndex;
   void (*v_destructor)(struct StorageImpl*);
-  
+
   /*
    * The following data members are specific to the Storage32Impl
@@ -341,60 +342,60 @@
   BlockChainStream* rootBlockChain;
   BlockChainStream* smallBlockDepotChain;
-  BlockChainStream* smallBlockRootChain;  
+  BlockChainStream* smallBlockRootChain;
 
   /*
    * Pointer to the big block file abstraction
    */
-  BigBlockFile* bigBlockFile; 
+  BigBlockFile* bigBlockFile;
 };
 
 /*
  * Method declaration for the Storage32Impl class
- */        
-
-HRESULT WINAPI StorageImpl_CreateStorage( 
+ */
+
+HRESULT WINAPI StorageImpl_CreateStorage(
             IStorage*      iface,
-            const OLECHAR* pwcsName,  /* [string][in] */ 
-            DWORD            grfMode,   /* [in] */ 
-            DWORD            dwStgFmt,  /* [in] */ 
-            DWORD            reserved2, /* [in] */ 
-            IStorage**     ppstg);    /* [out] */ 
-        
-HRESULT WINAPI StorageImpl_CopyTo( 
+            const OLECHAR* pwcsName,  /* [string][in] */
+            DWORD            grfMode,   /* [in] */
+            DWORD            dwStgFmt,  /* [in] */
+            DWORD            reserved2, /* [in] */
+            IStorage**     ppstg);    /* [out] */
+
+HRESULT WINAPI StorageImpl_CopyTo(
             IStorage*      iface,
-            DWORD          ciidExclude,  /* [in] */ 
-            const IID*     rgiidExclude, /* [size_is][unique][in] */ 
-            SNB            snbExclude, /* [unique][in] */ 
-            IStorage*    pstgDest);    /* [unique][in] */ 
-        
-HRESULT WINAPI StorageImpl_MoveElementTo( 
+            DWORD          ciidExclude,  /* [in] */
+            const IID*     rgiidExclude, /* [size_is][unique][in] */
+            SNB            snbExclude, /* [unique][in] */
+            IStorage*    pstgDest);    /* [unique][in] */
+
+HRESULT WINAPI StorageImpl_MoveElementTo(
             IStorage*      iface,
-            const OLECHAR* pwcsName,    /* [string][in] */ 
-            IStorage*      pstgDest,    /* [unique][in] */ 
-            const OLECHAR* pwcsNewName, /* [string][in] */ 
-            DWORD            grfFlags);   /* [in] */ 
-        
-HRESULT WINAPI StorageImpl_Commit( 
+            const OLECHAR* pwcsName,    /* [string][in] */
+            IStorage*      pstgDest,    /* [unique][in] */
+            const OLECHAR* pwcsNewName, /* [string][in] */
+            DWORD            grfFlags);   /* [in] */
+
+HRESULT WINAPI StorageImpl_Commit(
             IStorage*      iface,
-            DWORD          grfCommitFlags); /* [in] */ 
-        
-HRESULT WINAPI StorageImpl_Revert( 
+            DWORD          grfCommitFlags); /* [in] */
+
+HRESULT WINAPI StorageImpl_Revert(
             IStorage*      iface);
-        
-HRESULT WINAPI StorageImpl_DestroyElement( 
+
+HRESULT WINAPI StorageImpl_DestroyElement(
             IStorage*      iface,
-            const OLECHAR* pwcsName); /* [string][in] */ 
-        
-HRESULT WINAPI StorageImpl_SetElementTimes( 
+            const OLECHAR* pwcsName); /* [string][in] */
+
+HRESULT WINAPI StorageImpl_SetElementTimes(
             IStorage*      iface,
-            const OLECHAR* pwcsName, /* [string][in] */ 
-            const FILETIME*  pctime,   /* [in] */ 
-            const FILETIME*  patime,   /* [in] */ 
-            const FILETIME*  pmtime);  /* [in] */ 
-
-HRESULT WINAPI StorageImpl_SetStateBits( 
+            const OLECHAR* pwcsName, /* [string][in] */
+            const FILETIME*  pctime,   /* [in] */
+            const FILETIME*  patime,   /* [in] */
+            const FILETIME*  pmtime);  /* [in] */
+
+HRESULT WINAPI StorageImpl_SetStateBits(
             IStorage*      iface,
-            DWORD          grfStateBits, /* [in] */ 
-            DWORD          grfMask);     /* [in] */ 
+            DWORD          grfStateBits, /* [in] */
+            DWORD          grfMask);     /* [in] */
 
 HRESULT WINAPI StorageImpl_Stat(IStorage* iface,
@@ -443,12 +444,13 @@
 	    ULONG blockIndex);
 
-ULONG StorageImpl_GetNextBlockInChain(
-            StorageImpl* This,
-	    ULONG blockIndex);
+HRESULT StorageImpl_GetNextBlockInChain(
+            StorageImpl* This,
+	    ULONG blockIndex,
+	    ULONG* nextBlockIndex);
 
 void StorageImpl_SetNextBlockInChain(
             StorageImpl* This,
 	    ULONG blockIndex,
-      ULONG nextBlock);
+	    ULONG nextBlock);
 
 HRESULT StorageImpl_LoadFileHeader(
@@ -503,5 +505,5 @@
    */
   ULONG		             ref;
-  struct StorageImpl* ancestorStorage;		 
+  struct StorageImpl* ancestorStorage;
   ULONG                    rootPropertySetIndex;
   void (*v_destructor)(struct StorageInternalImpl*);
@@ -516,5 +518,5 @@
  */
 StorageInternalImpl* StorageInternalImpl_Construct(
-	    StorageImpl* ancestorStorage,	
+	    StorageImpl* ancestorStorage,
 	    ULONG          rootTropertyIndex);
 
@@ -522,9 +524,9 @@
        	    StorageInternalImpl* This);
 
-HRESULT WINAPI StorageInternalImpl_Commit( 
+HRESULT WINAPI StorageInternalImpl_Commit(
 	    IStorage*            iface,
-	    DWORD                  grfCommitFlags); /* [in] */ 
-
-HRESULT WINAPI StorageInternalImpl_Revert( 
+	    DWORD                  grfCommitFlags); /* [in] */
+
+HRESULT WINAPI StorageInternalImpl_Revert(
      	    IStorage*            iface);
 
@@ -541,5 +543,5 @@
   ICOM_VFIELD(IEnumSTATSTG);    /* Needs to be the first item in the struct
 					 * since we want to cast this in a IEnumSTATSTG pointer */
-  
+
   ULONG		 ref;		        /* Reference count */
   StorageImpl* parentStorage;         /* Reference to the parent storage */
@@ -565,11 +567,11 @@
 	    REFIID            riid,
 	    void**            ppvObject);
-        
+
 ULONG WINAPI IEnumSTATSTGImpl_AddRef(
-            IEnumSTATSTG*     iface); 
-        
+            IEnumSTATSTG*     iface);
+
 ULONG WINAPI IEnumSTATSTGImpl_Release(
             IEnumSTATSTG*     iface);
-        
+
 HRESULT WINAPI IEnumSTATSTGImpl_Next(
             IEnumSTATSTG*     iface,
@@ -577,12 +579,12 @@
 	    STATSTG*          rgelt,
 	    ULONG*            pceltFetched);
-        
+
 HRESULT WINAPI IEnumSTATSTGImpl_Skip(
             IEnumSTATSTG*     iface,
 	    ULONG             celt);
-        
+
 HRESULT WINAPI IEnumSTATSTGImpl_Reset(
             IEnumSTATSTG* iface);
-        
+
 HRESULT WINAPI IEnumSTATSTGImpl_Clone(
             IEnumSTATSTG*     iface,
@@ -626,5 +628,5 @@
   ICOM_VFIELD(IStream);  /* Needs to be the first item in the struct
 				    * since we want to cast this in a IStream pointer */
-  
+
   /*
    * Reference count
@@ -656,5 +658,5 @@
    */
   ULARGE_INTEGER     currentPosition;
-  
+
   /*
    * The information in the stream is represented by a chain of small blocks
@@ -682,74 +684,74 @@
 HRESULT WINAPI StgStreamImpl_QueryInterface(
 		IStream*      iface,
-		REFIID         riid,		/* [in] */          
-		void**         ppvObject);  /* [iid_is][out] */ 
-        
+		REFIID         riid,		/* [in] */
+		void**         ppvObject);  /* [iid_is][out] */
+
 ULONG WINAPI StgStreamImpl_AddRef(
 		IStream*      iface);
-        
+
 ULONG WINAPI StgStreamImpl_Release(
 		IStream*      iface);
-        
-HRESULT WINAPI StgStreamImpl_Read( 
+
+HRESULT WINAPI StgStreamImpl_Read(
 	        IStream*      iface,
 		void*          pv,        /* [length_is][size_is][out] */
-		ULONG          cb,        /* [in] */                     
-		ULONG*         pcbRead);  /* [out] */                    
-        
+		ULONG          cb,        /* [in] */
+		ULONG*         pcbRead);  /* [out] */
+
 HRESULT WINAPI StgStreamImpl_Write(
 		IStream*      iface,
-		const void*    pv,          /* [size_is][in] */ 
-		ULONG          cb,          /* [in] */          
-		ULONG*         pcbWritten); /* [out] */         
-        
-HRESULT WINAPI StgStreamImpl_Seek( 
+		const void*    pv,          /* [size_is][in] */
+		ULONG          cb,          /* [in] */
+		ULONG*         pcbWritten); /* [out] */
+
+HRESULT WINAPI StgStreamImpl_Seek(
 		IStream*      iface,
-		LARGE_INTEGER   dlibMove,         /* [in] */ 
-		DWORD           dwOrigin,         /* [in] */ 
+		LARGE_INTEGER   dlibMove,         /* [in] */
+		DWORD           dwOrigin,         /* [in] */
 		ULARGE_INTEGER* plibNewPosition); /* [out] */
-        
-HRESULT WINAPI StgStreamImpl_SetSize( 
+
+HRESULT WINAPI StgStreamImpl_SetSize(
 	        IStream*      iface,
-		ULARGE_INTEGER  libNewSize);  /* [in] */ 
-        
-HRESULT WINAPI StgStreamImpl_CopyTo( 
+		ULARGE_INTEGER  libNewSize);  /* [in] */
+
+HRESULT WINAPI StgStreamImpl_CopyTo(
 		IStream*      iface,
-		IStream*      pstm,         /* [unique][in] */ 
-		ULARGE_INTEGER  cb,           /* [in] */         
-		ULARGE_INTEGER* pcbRead,      /* [out] */        
-		ULARGE_INTEGER* pcbWritten);  /* [out] */        
-
-HRESULT WINAPI StgStreamImpl_Commit( 
+		IStream*      pstm,         /* [unique][in] */
+		ULARGE_INTEGER  cb,           /* [in] */
+		ULARGE_INTEGER* pcbRead,      /* [out] */
+		ULARGE_INTEGER* pcbWritten);  /* [out] */
+
+HRESULT WINAPI StgStreamImpl_Commit(
 	    	IStream*      iface,
-		DWORD           grfCommitFlags); /* [in] */ 
-        
-HRESULT WINAPI StgStreamImpl_Revert( 
+		DWORD           grfCommitFlags); /* [in] */
+
+HRESULT WINAPI StgStreamImpl_Revert(
 		IStream*  iface);
-        
-HRESULT WINAPI StgStreamImpl_LockRegion( 
+
+HRESULT WINAPI StgStreamImpl_LockRegion(
 		IStream*     iface,
-		ULARGE_INTEGER libOffset,   /* [in] */ 
-		ULARGE_INTEGER cb,          /* [in] */ 
-		DWORD          dwLockType); /* [in] */ 
-        
-HRESULT WINAPI StgStreamImpl_UnlockRegion( 
+		ULARGE_INTEGER libOffset,   /* [in] */
+		ULARGE_INTEGER cb,          /* [in] */
+		DWORD          dwLockType); /* [in] */
+
+HRESULT WINAPI StgStreamImpl_UnlockRegion(
 		IStream*     iface,
-		ULARGE_INTEGER libOffset,   /* [in] */ 
-	        ULARGE_INTEGER cb,          /* [in] */ 
-		DWORD          dwLockType); /* [in] */ 
-        
-HRESULT WINAPI StgStreamImpl_Stat( 
+		ULARGE_INTEGER libOffset,   /* [in] */
+	        ULARGE_INTEGER cb,          /* [in] */
+		DWORD          dwLockType); /* [in] */
+
+HRESULT WINAPI StgStreamImpl_Stat(
 		IStream*     iface,
 	        STATSTG*       pstatstg,     /* [out] */
-	        DWORD          grfStatFlag); /* [in] */ 
-        
-HRESULT WINAPI StgStreamImpl_Clone( 
+	        DWORD          grfStatFlag); /* [in] */
+
+HRESULT WINAPI StgStreamImpl_Clone(
 		IStream*     iface,
-		IStream**    ppstm);       /* [out] */ 
+		IStream**    ppstm);       /* [out] */
 
 
 /********************************************************************************
  * The StorageUtl_ functions are miscelaneous utility functions. Most of which are
- * abstractions used to read values from file buffers without having to worry 
+ * abstractions used to read values from file buffers without having to worry
  * about bit order
  */
@@ -785,5 +787,5 @@
  */
 BlockChainStream* BlockChainStream_Construct(
-		StorageImpl* parentStorage,	
+		StorageImpl* parentStorage,
 		ULONG*         headOfStreamPlaceHolder,
 		ULONG          propertyIndex);
@@ -835,5 +837,5 @@
  */
 SmallBlockChainStream* SmallBlockChainStream_Construct(
-	       StorageImpl* parentStorage,	
+	       StorageImpl* parentStorage,
 	       ULONG          propertyIndex);
 
@@ -844,7 +846,8 @@
 	       SmallBlockChainStream* This);
 
-ULONG SmallBlockChainStream_GetNextBlockInChain(
+HRESULT SmallBlockChainStream_GetNextBlockInChain(
 	       SmallBlockChainStream* This,
-	       ULONG                  blockIndex);
+	       ULONG                  blockIndex,
+	       ULONG*                 nextBlockIndex);
 
 void SmallBlockChainStream_SetNextBlockInChain(
@@ -886,5 +889,2 @@
 
 #endif /* __STORAGE32_H__ */
-
-
-
Index: trunk/src/ole32/stubs.cpp
===================================================================
--- trunk/src/ole32/stubs.cpp	(revision 9394)
+++ trunk/src/ole32/stubs.cpp	(revision 9400)
@@ -1,3 +1,3 @@
-/* $Id: stubs.cpp,v 1.21 2002-02-19 12:34:50 sandervl Exp $ */
+/* $Id: stubs.cpp,v 1.22 2002-11-12 17:06:03 sandervl Exp $ */
 /* 
  * Win32 COM/OLE stubs for OS/2
@@ -80,22 +80,8 @@
 //*******************************************************************************
 //*******************************************************************************
-HRESULT WIN32API CoRegisterMallocSpy(LPMALLOCSPY pMallocSpy)
-{
-    dprintf(("OLE32: CoRegisterMallocSpy - stub"));
-    return CO_E_OBJISREG;
-}
-//*******************************************************************************
-//*******************************************************************************
 HRESULT WIN32API CoReleaseMarshalData(IStream *pStm)
 {
     dprintf(("OLE32: CoReleaseMarshalData - stub"));
     return E_OUTOFMEMORY;
-}
-//*******************************************************************************
-//*******************************************************************************
-HRESULT WIN32API CoRevokeMallocSpy()
-{
-    dprintf(("OLE32: CoRevokeMallocSpy - stub"));
-    return E_ACCESSDENIED;
 }
 //*******************************************************************************
@@ -337,21 +323,4 @@
 {
     dprintf(("OLE32: CoImpersonateClient - Stub"));
-    return(S_OK);
-}
-
-//*******************************************************************************
-//*******************************************************************************
-HRESULT WIN32API CoInitializeSecurity(		// DCOM - obj_clientserver.h
-    PSECURITY_DESCRIPTOR         pSecDesc,
-    LONG                         cAuthSvc,
-    SOLE_AUTHENTICATION_SERVICE *asAuthSvc,
-    void                        *pReserved1,
-    DWORD                        dwAuthnLevel,
-    DWORD                        dwImpLevel,
-    void                        *pReserved2,
-    DWORD                        dwCapabilities,
-    void                        *pReserved3 )
-{
-    dprintf(("OLE32: CoInitializeSecurity - Stub"));
     return(S_OK);
 }
Index: trunk/src/oleaut32/dbgwrap.cpp
===================================================================
--- trunk/src/oleaut32/dbgwrap.cpp	(revision 9394)
+++ trunk/src/oleaut32/dbgwrap.cpp	(revision 9400)
@@ -303,4 +303,15 @@
 NODEF_DEBUGWRAP16(VarBstrCmp)
 DEBUGWRAP12(VarCat)
-
-
+NODEF_DEBUGWRAP8(SafeArrayGetVartype)
+NODEF_DEBUGWRAP24(VarFormat)
+NODEF_DEBUGWRAP16(VarFormatDateTime)
+//NODEF_DEBUGWRAP28(VarFormatNumber)
+//NODEF_DEBUGWRAP28(VarFormatPercent)
+NODEF_DEBUGWRAP28(VarFormatCurrency)
+NODEF_DEBUGWRAP24(VarFormatFromTokens)
+NODEF_DEBUGWRAP28(VarTokenizeFormatString)
+DEBUGWRAP12(VarAnd)
+DEBUGWRAP8(VarNot)
+DEBUGWRAP16(VarCmp)
+NODEF_DEBUGWRAP16(VarCyMulI4)
+
Index: trunk/src/oleaut32/ole2disp.c
===================================================================
--- trunk/src/oleaut32/ole2disp.c	(revision 9394)
+++ trunk/src/oleaut32/ole2disp.c	(revision 9400)
@@ -76,7 +76,7 @@
 {
 	BSTR16 out;
-    
+
 	if (!in) return 0;
-    
+
 	out = BSTR_AllocBytes(strlen(in)+1);
 	if (!out) return 0;
@@ -95,5 +95,5 @@
 {
     if (!in) return 0;
-    
+
     /* Delegate this to the SysAllocStringLen32 method. */
     return SysAllocStringLen(in, lstrlenW(in));
@@ -119,5 +119,5 @@
      * Sanity check
      */
-    if (old==NULL) 
+    if (old==NULL)
       return 0;
 
@@ -125,5 +125,5 @@
      * Make sure we free the old string.
      */
-    if (*old!=NULL)      
+    if (*old!=NULL)
       SysFreeString(*old);
 
@@ -166,5 +166,5 @@
  * he describes it as a "DWORD count of characters". By experimenting with
  * a windows application, this count seems to be a DWORD count of bytes in
- * the string. Meaning that the count is double the number of wide 
+ * the string. Meaning that the count is double the number of wide
  * characters in the string.
  */
@@ -237,5 +237,5 @@
 }
 
- 
+
 /******************************************************************************
  *             SysReAllocStringLen   [OLEAUT32.5]
@@ -246,5 +246,5 @@
      * Sanity check
      */
-    if (old==NULL) 
+    if (old==NULL)
       return 0;
 
@@ -252,5 +252,5 @@
      * Make sure we free the old string.
      */
-    if (*old!=NULL)      
+    if (*old!=NULL)
       SysFreeString(*old);
 
@@ -277,5 +277,5 @@
 {
     DWORD* bufferPointer;
-    
+
     /* NULL is a valid parameter */
     if(!in) return;
@@ -318,5 +318,5 @@
      if (!str) return 0;
     /*
-     * The length of the string (in bytes) is contained in a DWORD placed 
+     * The length of the string (in bytes) is contained in a DWORD placed
      * just before the BSTR pointer
      */
@@ -342,5 +342,5 @@
      if (!str) return 0;
     /*
-     * The length of the string (in bytes) is contained in a DWORD placed 
+     * The length of the string (in bytes) is contained in a DWORD placed
      * just before the BSTR pointer
      */
@@ -419,5 +419,5 @@
  * Converts an OLE_COLOR to a COLORREF.
  * See the documentation for conversion rules.
- * pColorRef can be NULL. In that case the user only wants to test the 
+ * pColorRef can be NULL. In that case the user only wants to test the
  * conversion.
  */
@@ -430,5 +430,5 @@
   BYTE b = HIBYTE(HIWORD(clr));
 
-  TRACE("(%08lx, %d, %p):stub\n", clr, hpal, pColorRef);
+  TRACE("(%08lx, %p, %p):stub\n", clr, hpal, pColorRef);
 
   /*
Index: trunk/src/oleaut32/oleaut32.def
===================================================================
--- trunk/src/oleaut32/oleaut32.def	(revision 9394)
+++ trunk/src/oleaut32/oleaut32.def	(revision 9400)
@@ -1,3 +1,3 @@
-;/* $Id: oleaut32.def,v 1.9 2002-02-15 15:07:37 sandervl Exp $ */
+;/* $Id: oleaut32.def,v 1.10 2002-11-12 17:07:46 sandervl Exp $ */
 LIBRARY OLAUTOS2 INITINSTANCE
 DESCRIPTION 'Odin32 System DLL - OleAut32'
@@ -5,185 +5,214 @@
 
 EXPORTS
-DllGetClassObject = _OLEAUT32_DllGetClassObject@12  @1
-SysAllocString = _SysAllocString@4  @2
-SysReAllocString = _SysReAllocString@8  @3
-SysAllocStringLen = _SysAllocStringLen@8  @4
-SysReAllocStringLen = _SysReAllocStringLen@12  @5
-SysFreeString = _SysFreeString@4  @6
-SysStringLen = _SysStringLen@4  @7
-VariantInit = _VariantInit@4  @8
-VariantClear = _VariantClear@4  @9
-VariantCopy = _VariantCopy@8  @10
-VariantCopyInd = _VariantCopyInd@8  @11
-VariantChangeType = _VariantChangeType@16  @12
-VariantTimeToDosDateTime = _VariantTimeToDosDateTime@16  @13
-DosDateTimeToVariantTime = _DosDateTimeToVariantTime@12  @14
-SafeArrayCreate = _SafeArrayCreate@12  @15
-SafeArrayDestroy = _SafeArrayDestroy@4  @16
-SafeArrayGetDim = _SafeArrayGetDim@4  @17
-SafeArrayGetElemsize = _SafeArrayGetElemsize@4  @18
-SafeArrayGetUBound = _SafeArrayGetUBound@12  @19
-SafeArrayGetLBound = _SafeArrayGetLBound@12  @20
-SafeArrayLock = _SafeArrayLock@4  @21
-SafeArrayUnlock = _SafeArrayUnlock@4  @22
-SafeArrayAccessData = _SafeArrayAccessData@8  @23
-SafeArrayUnaccessData = _SafeArrayUnaccessData@4  @24
-SafeArrayGetElement = _SafeArrayGetElement@12  @25
-SafeArrayPutElement = _SafeArrayPutElement@12  @26
-SafeArrayCopy = _SafeArrayCopy@8  @27
-DispGetParam = _DispGetParam@20  @28
-DispGetIDsOfNames = _DispGetIDsOfNames@16  @29
-DispInvoke = _DispInvoke@32  @30
-CreateDispTypeInfo = _CreateDispTypeInfo@12  @31
-CreateStdDispatch = _CreateStdDispatch@16  @32
-RegisterActiveObject = _RegisterActiveObject@16  @33
-RevokeActiveObject = _RevokeActiveObject@8  @34
-GetActiveObject = _GetActiveObject@12  @35
-SafeArrayAllocDescriptor = _SafeArrayAllocDescriptor@8  @36
-SafeArrayAllocData = _SafeArrayAllocData@4  @37
-SafeArrayDestroyDescriptor = _SafeArrayDestroyDescriptor@4  @38
-SafeArrayDestroyData = _SafeArrayDestroyData@4  @39
-SafeArrayRedim = _SafeArrayRedim@8  @40
-OACreateTypeLib2 = _OACreateTypeLib2@0  @41
-VarParseNumFromStr = _VarParseNumFromStr@20  @46
-VarNumFromParseNum = _VarNumFromParseNum@16  @47
-VarI2FromUI1 = _VarI2FromUI1@8  @48
-VarI2FromI4 = _VarI2FromI4@8  @49
-VarI2FromR4 = _VarI2FromR4@8  @50
-VarI2FromR8 = _VarI2FromR8@12  @51
-VarI2FromCy = _VarI2FromCy@12  @52
-VarI2FromDate = _VarI2FromDate@12  @53
-VarI2FromStr = _VarI2FromStr@16  @54
-VarI2FromDisp = _VarI2FromDisp@12  @55
-VarI2FromBool = _VarI2FromBool@8  @56
-VarI4FromUI1 = _VarI4FromUI1@8  @58
-VarI4FromI2 = _VarI4FromI2@8  @59
-VarI4FromR4 = _VarI4FromR4@8  @60
-VarI4FromR8 = _VarI4FromR8@12  @61
-VarI4FromCy = _VarI4FromCy@12  @62
-VarI4FromDate = _VarI4FromDate@12  @63
-VarI4FromStr = _VarI4FromStr@16  @64
-VarI4FromDisp = _VarI4FromDisp@12  @65
-VarI4FromBool = _VarI4FromBool@8  @66
-VarR4FromUI1 = _VarR4FromUI1@8  @68
-VarR4FromI2 = _VarR4FromI2@8  @69
-VarR4FromI4 = _VarR4FromI4@8  @70
-VarR4FromR8 = _VarR4FromR8@12  @71
-VarR4FromCy = _VarR4FromCy@12  @72
-VarR4FromDate = _VarR4FromDate@12  @73
-VarR4FromStr = _VarR4FromStr@16  @74
-VarR4FromDisp = _VarR4FromDisp@12  @75
-VarR4FromBool = _VarR4FromBool@8  @76
-VarR8FromUI1 = _VarR8FromUI1@8  @78
-VarR8FromI2 = _VarR8FromI2@8  @79
-VarR8FromI4 = _VarR8FromI4@8  @80
-VarR8FromR4 = _VarR8FromR4@8  @81
-VarR8FromCy = _VarR8FromCy@12  @82
-VarR8FromDate = _VarR8FromDate@12  @83
-VarR8FromStr = _VarR8FromStr@16  @84
-VarR8FromDisp = _VarR8FromDisp@12  @85
-VarR8FromBool = _VarR8FromBool@8  @86
-VarDateFromUI1 = _VarDateFromUI1@8  @88
-VarDateFromI2 = _VarDateFromI2@8  @89
-VarDateFromI4 = _VarDateFromI4@8  @90
-VarDateFromR4 = _VarDateFromR4@8  @91
-VarDateFromR8 = _VarDateFromR8@12  @92
-VarDateFromCy = _VarDateFromCy@12  @93
-VarDateFromStr = _VarDateFromStr@16  @94
-VarDateFromDisp = _VarDateFromDisp@12  @95
-VarDateFromBool = _VarDateFromBool@8  @96
-VarCyFromUI1 = _VarCyFromUI1@8  @98
-VarCyFromI2 = _VarCyFromI2@8  @99
-VarCyFromI4 = _VarCyFromI4@8  @100
-VarCyFromR4 = _VarCyFromR4@8  @101
-VarCyFromR8 = _VarCyFromR8@12  @102
-VarCyFromDate = _VarCyFromDate@12  @103
-VarCyFromStr = _VarCyFromStr@16  @104
-VarCyFromDisp = _VarCyFromDisp@12  @105
-VarCyFromBool = _VarCyFromBool@8  @106
-VarBstrFromUI1 = _VarBstrFromUI1@16  @108
-VarBstrFromI2 = _VarBstrFromI2@16  @109
-VarBstrFromI4 = _VarBstrFromI4@16  @110
-VarBstrFromR4 = _VarBstrFromR4@16  @111
-VarBstrFromR8 = _VarBstrFromR8@20  @112
-VarBstrFromCy = _VarBstrFromCy@20  @113
-VarBstrFromDate = _VarBstrFromDate@20  @114
-VarBstrFromDisp = _VarBstrFromDisp@16  @115
-VarBstrFromBool = _VarBstrFromBool@16  @116
-VarBoolFromUI1 = _VarBoolFromUI1@8  @118
-VarBoolFromI2 = _VarBoolFromI2@8  @119
-VarBoolFromI4 = _VarBoolFromI4@8  @120
-VarBoolFromR4 = _VarBoolFromR4@8  @121
-VarBoolFromR8 = _VarBoolFromR8@12  @122
-VarBoolFromDate = _VarBoolFromDate@12  @123
-VarBoolFromCy = _VarBoolFromCy@12  @124
-VarBoolFromStr = _VarBoolFromStr@16  @125
-VarBoolFromDisp = _VarBoolFromDisp@12  @126
-VarUI1FromI2 = _VarUI1FromI2@8  @130
-VarUI1FromI4 = _VarUI1FromI4@8  @131
-VarUI1FromR4 = _VarUI1FromR4@8  @132
-VarUI1FromR8 = _VarUI1FromR8@12  @133
-VarUI1FromCy = _VarUI1FromCy@12  @134
-VarUI1FromDate = _VarUI1FromDate@12  @135
-VarUI1FromStr = _VarUI1FromStr@16  @136
-VarUI1FromDisp = _VarUI1FromDisp@12  @137
-VarUI1FromBool = _VarUI1FromBool@8  @138
-DispCallFunc = _DispCallFunc@32  @146
-VariantChangeTypeEx = _VariantChangeTypeEx@20  @147
-SafeArrayPtrOfIndex = _SafeArrayPtrOfIndex@12  @148
-SysStringByteLen = _SysStringByteLen@4  @149
-SysAllocStringByteLen = _SysAllocStringByteLen@8  @150
-CreateTypeLib = _CreateTypeLib@12  @160
-LoadTypeLib = _LoadTypeLib@8  @161
-LoadRegTypeLib = _LoadRegTypeLib@20  @162
-RegisterTypeLib = _RegisterTypeLib@12  @163
-QueryPathOfRegTypeLib = _QueryPathOfRegTypeLib@20  @164
-LHashValOfNameSys = _LHashValOfNameSys@12  @165
-LHashValOfNameSysA = _LHashValOfNameSysA@12  @166
-OaBuildVersion = _OaBuildVersion@0  @170
-ClearCustData = _ClearCustData@4  @171
-CreateTypeLib2 = _CreateTypeLib2@12  @180
-LoadTypeLibEx = _LoadTypeLibEx@12  @183
-SystemTimeToVariantTime = _SystemTimeToVariantTime@8  @184
-VariantTimeToSystemTime = _VariantTimeToSystemTime@12  @185
-UnRegisterTypeLib = _UnRegisterTypeLib@20  @186
-VarDecFromUI1 = _VarDecFromUI1@8  @190
-VarDecFromI2 = _VarDecFromI2@8  @191
-VarDecFromI4 = _VarDecFromI4@8  @192
-VarDecFromR4 = _VarDecFromR4@8  @193
-VarDecFromR8 = _VarDecFromR8@12  @194
-VarDecFromDate = _VarDecFromDate@12  @195
-VarDecFromCy = _VarDecFromCy@12  @196
-VarDecFromStr = _VarDecFromStr@16  @197
-VarDecFromDisp = _VarDecFromDisp@12  @198
-VarDecFromBool = _VarDecFromBool@8  @199
-GetErrorInfo = _GetErrorInfo@8  @200
-SetErrorInfo = _SetErrorInfo@8  @201
-CreateErrorInfo = _CreateErrorInfo@4  @202
-VarI2FromI1 = _VarI2FromI1@8  @205
-VarI2FromUI2 = _VarI2FromUI2@8  @206
-VarI2FromUI4 = _VarI2FromUI4@8  @207
-VarI2FromDec = _VarI2FromDec@8  @208
-VarI4FromI1 = _VarI4FromI1@8  @209
-VarI4FromUI2 = _VarI4FromUI2@8  @210
-VarI4FromUI4 = _VarI4FromUI4@8  @211
-VarI4FromDec = _VarI4FromDec@8  @212
-VarR4FromI1 = _VarR4FromI1@8  @213
-VarR4FromUI2 = _VarR4FromUI2@8  @214
-VarR4FromUI4 = _VarR4FromUI4@8  @215
-VarR4FromDec = _VarR4FromDec@8  @216
-VarR8FromI1 = _VarR8FromI1@8  @217
-VarR8FromUI2 = _VarR8FromUI2@8  @218
-VarR8FromUI4 = _VarR8FromUI4@8  @219
-VarR8FromDec = _VarR8FromDec@8  @220
-VarDateFromI1 = _VarDateFromI1@8  @221
-VarDateFromUI2 = _VarDateFromUI2@8  @222
-VarDateFromUI4 = _VarDateFromUI4@8  @223
-VarDateFromDec = _VarDateFromDec@8  @224
-VarCyFromI1 = _VarCyFromI1@8  @225
-VarCyFromUI2 = _VarCyFromUI2@8  @226
-VarCyFromUI4 = _VarCyFromUI4@8  @227
-VarCyFromDec = _VarCyFromDec@8  @228
-VarBstrFromI1 = _VarBstrFromI1@16  @229
+  DllGetClassObject = _OLEAUT32_DllGetClassObject@12  @1
+  SysAllocString = _SysAllocString@4  @2
+  SysReAllocString = _SysReAllocString@8  @3
+  SysAllocStringLen = _SysAllocStringLen@8  @4
+  SysReAllocStringLen = _SysReAllocStringLen@12  @5
+  SysFreeString = _SysFreeString@4  @6
+  SysStringLen = _SysStringLen@4  @7
+  VariantInit = _VariantInit@4  @8
+  VariantClear = _VariantClear@4  @9
+  VariantCopy = _VariantCopy@8  @10
+  VariantCopyInd = _VariantCopyInd@8  @11
+  VariantChangeType = _VariantChangeType@16  @12
+  VariantTimeToDosDateTime = _VariantTimeToDosDateTime@16  @13
+  DosDateTimeToVariantTime = _DosDateTimeToVariantTime@12  @14
+  SafeArrayCreate = _SafeArrayCreate@12  @15
+  SafeArrayDestroy = _SafeArrayDestroy@4  @16
+  SafeArrayGetDim = _SafeArrayGetDim@4  @17
+  SafeArrayGetElemsize = _SafeArrayGetElemsize@4  @18
+  SafeArrayGetUBound = _SafeArrayGetUBound@12  @19
+  SafeArrayGetLBound = _SafeArrayGetLBound@12  @20
+  SafeArrayLock = _SafeArrayLock@4  @21
+  SafeArrayUnlock = _SafeArrayUnlock@4  @22
+  SafeArrayAccessData = _SafeArrayAccessData@8  @23
+  SafeArrayUnaccessData = _SafeArrayUnaccessData@4  @24
+  SafeArrayGetElement = _SafeArrayGetElement@12  @25
+  SafeArrayPutElement = _SafeArrayPutElement@12  @26
+  SafeArrayCopy = _SafeArrayCopy@8  @27
+  DispGetParam = _DispGetParam@20  @28
+  DispGetIDsOfNames = _DispGetIDsOfNames@16  @29
+  DispInvoke = _DispInvoke@32  @30
+  CreateDispTypeInfo = _CreateDispTypeInfo@12  @31
+  CreateStdDispatch = _CreateStdDispatch@16  @32
+  RegisterActiveObject = _RegisterActiveObject@16  @33
+  RevokeActiveObject = _RevokeActiveObject@8  @34
+  GetActiveObject = _GetActiveObject@12  @35
+  SafeArrayAllocDescriptor = _SafeArrayAllocDescriptor@8  @36
+  SafeArrayAllocData = _SafeArrayAllocData@4  @37
+  SafeArrayDestroyDescriptor = _SafeArrayDestroyDescriptor@4  @38
+  SafeArrayDestroyData = _SafeArrayDestroyData@4  @39
+  SafeArrayRedim = _SafeArrayRedim@8  @40
+  OACreateTypeLib2 = _OACreateTypeLib2@0  @41
+  VarParseNumFromStr = _VarParseNumFromStr@20  @46
+  VarNumFromParseNum = _VarNumFromParseNum@16  @47
+  VarI2FromUI1 = _VarI2FromUI1@8  @48
+  VarI2FromI4 = _VarI2FromI4@8  @49
+  VarI2FromR4 = _VarI2FromR4@8  @50
+  VarI2FromR8 = _VarI2FromR8@12  @51
+  VarI2FromCy = _VarI2FromCy@12  @52
+  VarI2FromDate = _VarI2FromDate@12  @53
+  VarI2FromStr = _VarI2FromStr@16  @54
+  VarI2FromDisp = _VarI2FromDisp@12  @55
+  VarI2FromBool = _VarI2FromBool@8  @56
+  VarI4FromUI1 = _VarI4FromUI1@8  @58
+  VarI4FromI2 = _VarI4FromI2@8  @59
+  VarI4FromR4 = _VarI4FromR4@8  @60
+  VarI4FromR8 = _VarI4FromR8@12  @61
+  VarI4FromCy = _VarI4FromCy@12  @62
+  VarI4FromDate = _VarI4FromDate@12  @63
+  VarI4FromStr = _VarI4FromStr@16  @64
+  VarI4FromDisp = _VarI4FromDisp@12  @65
+  VarI4FromBool = _VarI4FromBool@8  @66
+  VarR4FromUI1 = _VarR4FromUI1@8  @68
+  VarR4FromI2 = _VarR4FromI2@8  @69
+
+  VarR4FromI4                 = _VarR4FromI4@8                  @70
+  VarR4FromR8                 = _VarR4FromR8@12                 @71
+  VarR4FromCy                 = _VarR4FromCy@12                 @72
+  VarR4FromDate               = _VarR4FromDate@12               @73
+  VarR4FromStr                = _VarR4FromStr@16                @74
+  VarR4FromDisp               = _VarR4FromDisp@12               @75
+  VarR4FromBool               = _VarR4FromBool@8                @76
+  SafeArrayGetVartype         = _SafeArrayGetVartype@8          @77
+  VarR8FromUI1                = _VarR8FromUI1@8                 @78
+  VarR8FromI2                 = _VarR8FromI2@8                  @79
+
+  VarR8FromI4                 = _VarR8FromI4@8                  @80
+  VarR8FromR4                 = _VarR8FromR4@8                  @81
+  VarR8FromCy                 = _VarR8FromCy@12                 @82
+  VarR8FromDate               = _VarR8FromDate@12               @83
+  VarR8FromStr                = _VarR8FromStr@16                @84
+  VarR8FromDisp               = _VarR8FromDisp@12               @85
+  VarR8FromBool               = _VarR8FromBool@8                @86
+  VarFormat                   = _VarFormat@24                   @87
+  VarDateFromUI1              = _VarDateFromUI1@8               @88
+  VarDateFromI2               = _VarDateFromI2@8                @89
+
+  VarDateFromI4               = _VarDateFromI4@8                @90
+  VarDateFromR4               = _VarDateFromR4@8                @91
+  VarDateFromR8               = _VarDateFromR8@12               @92
+  VarDateFromCy               = _VarDateFromCy@12               @93
+  VarDateFromStr              = _VarDateFromStr@16              @94
+  VarDateFromDisp             = _VarDateFromDisp@12             @95
+  VarDateFromBool             = _VarDateFromBool@8              @96
+  VarFormatDateTime           = _VarFormatDateTime@16           @97
+  VarCyFromUI1                = _VarCyFromUI1@8                 @98
+  VarCyFromI2                 = _VarCyFromI2@8                  @99
+
+  VarCyFromI4                 = _VarCyFromI4@8                  @100
+  VarCyFromR4                 = _VarCyFromR4@8                  @101
+  VarCyFromR8                 = _VarCyFromR8@12                 @102
+  VarCyFromDate               = _VarCyFromDate@12               @103
+  VarCyFromStr                = _VarCyFromStr@16                @104
+  VarCyFromDisp               = _VarCyFromDisp@12               @105
+  VarCyFromBool               = _VarCyFromBool@8                @106
+;;  VarFormatNumber             = _VarFormatNumber@28             @107
+  VarBstrFromUI1              = _VarBstrFromUI1@16              @108
+  VarBstrFromI2               = _VarBstrFromI2@16               @109
+
+  VarBstrFromI4               = _VarBstrFromI4@16               @110
+  VarBstrFromR4               = _VarBstrFromR4@16               @111
+  VarBstrFromR8               = _VarBstrFromR8@20               @112
+  VarBstrFromCy               = _VarBstrFromCy@20               @113
+  VarBstrFromDate             = _VarBstrFromDate@20             @114
+  VarBstrFromDisp             = _VarBstrFromDisp@16             @115
+  VarBstrFromBool             = _VarBstrFromBool@16             @116
+;;  VarFormatPercent            = _VarFormatPercent@28            @117
+  VarBoolFromUI1              = _VarBoolFromUI1@8               @118
+  VarBoolFromI2               = _VarBoolFromI2@8                @119
+
+  VarBoolFromI4               = _VarBoolFromI4@8                @120
+  VarBoolFromR4               = _VarBoolFromR4@8                @121
+  VarBoolFromR8               = _VarBoolFromR8@12               @122
+  VarBoolFromDate             = _VarBoolFromDate@12             @123
+  VarBoolFromCy               = _VarBoolFromCy@12               @124
+  VarBoolFromStr              = _VarBoolFromStr@16              @125
+  VarBoolFromDisp             = _VarBoolFromDisp@12             @126
+  VarFormatCurrency           = _VarFormatCurrency@28           @127
+
+  VarUI1FromI2                = _VarUI1FromI2@8                 @130
+  VarUI1FromI4                = _VarUI1FromI4@8                 @131
+  VarUI1FromR4                = _VarUI1FromR4@8                 @132
+  VarUI1FromR8                = _VarUI1FromR8@12                @133
+  VarUI1FromCy                = _VarUI1FromCy@12                @134
+  VarUI1FromDate              = _VarUI1FromDate@12              @135
+  VarUI1FromStr               = _VarUI1FromStr@16               @136
+  VarUI1FromDisp              = _VarUI1FromDisp@12              @137
+  VarUI1FromBool              = _VarUI1FromBool@8               @138
+  VarFormatFromTokens         = _VarFormatFromTokens@24         @139
+
+  VarTokenizeFormatString     = _VarTokenizeFormatString@28     @140
+  VarAnd                      = _VarAnd@12                      @142
+
+  DispCallFunc                = _DispCallFunc@32                @146
+  VariantChangeTypeEx         = _VariantChangeTypeEx@20         @147
+  SafeArrayPtrOfIndex         = _SafeArrayPtrOfIndex@12         @148
+  SysStringByteLen            = _SysStringByteLen@4             @149
+
+  SysAllocStringByteLen       = _SysAllocStringByteLen@8        @150
+
+  CreateTypeLib               = _CreateTypeLib@12               @160
+  LoadTypeLib                 = _LoadTypeLib@8                  @161
+  LoadRegTypeLib              = _LoadRegTypeLib@20              @162
+  RegisterTypeLib             = _RegisterTypeLib@12             @163
+  QueryPathOfRegTypeLib       = _QueryPathOfRegTypeLib@20       @164
+  LHashValOfNameSys           = _LHashValOfNameSys@12           @165
+  LHashValOfNameSysA          = _LHashValOfNameSysA@12          @166
+
+  OaBuildVersion              = _OaBuildVersion@0               @170
+  ClearCustData               = _ClearCustData@4                @171
+  VarNot                      = _VarNot@8                       @174
+  VarCmp                      = _VarCmp@16                      @176
+
+  CreateTypeLib2              = _CreateTypeLib2@12              @180
+  LoadTypeLibEx               = _LoadTypeLibEx@12               @183
+  SystemTimeToVariantTime     = _SystemTimeToVariantTime@8      @184
+  VariantTimeToSystemTime     = _VariantTimeToSystemTime@12     @185
+  UnRegisterTypeLib           = _UnRegisterTypeLib@20           @186
+
+  VarDecFromUI1               = _VarDecFromUI1@8                @190
+  VarDecFromI2                = _VarDecFromI2@8                 @191
+  VarDecFromI4                = _VarDecFromI4@8                 @192
+  VarDecFromR4                = _VarDecFromR4@8                 @193
+  VarDecFromR8                = _VarDecFromR8@12                @194
+  VarDecFromDate              = _VarDecFromDate@12              @195
+  VarDecFromCy                = _VarDecFromCy@12                @196
+  VarDecFromStr               = _VarDecFromStr@16               @197
+  VarDecFromDisp              = _VarDecFromDisp@12              @198
+  VarDecFromBool              = _VarDecFromBool@8               @199
+
+  GetErrorInfo = _GetErrorInfo@8  @200
+  SetErrorInfo = _SetErrorInfo@8  @201
+  CreateErrorInfo = _CreateErrorInfo@4  @202
+  VarI2FromI1 = _VarI2FromI1@8  @205
+  VarI2FromUI2 = _VarI2FromUI2@8  @206
+  VarI2FromUI4 = _VarI2FromUI4@8  @207
+  VarI2FromDec = _VarI2FromDec@8  @208
+  VarI4FromI1 = _VarI4FromI1@8  @209
+  VarI4FromUI2 = _VarI4FromUI2@8  @210
+
+  VarI4FromUI4 = _VarI4FromUI4@8  @211
+  VarI4FromDec = _VarI4FromDec@8  @212
+  VarR4FromI1 = _VarR4FromI1@8  @213
+  VarR4FromUI2 = _VarR4FromUI2@8  @214
+  VarR4FromUI4 = _VarR4FromUI4@8  @215
+  VarR4FromDec = _VarR4FromDec@8  @216
+  VarR8FromI1 = _VarR8FromI1@8  @217
+  VarR8FromUI2 = _VarR8FromUI2@8  @218
+  VarR8FromUI4 = _VarR8FromUI4@8  @219
+
+  VarR8FromDec = _VarR8FromDec@8  @220
+  VarDateFromI1 = _VarDateFromI1@8  @221
+  VarDateFromUI2 = _VarDateFromUI2@8  @222
+  VarDateFromUI4 = _VarDateFromUI4@8  @223
+  VarDateFromDec = _VarDateFromDec@8  @224
+  VarCyFromI1 = _VarCyFromI1@8  @225
+  VarCyFromUI2 = _VarCyFromUI2@8  @226
+  VarCyFromUI4 = _VarCyFromUI4@8  @227
+  VarCyFromDec = _VarCyFromDec@8  @228
+  VarBstrFromI1 = _VarBstrFromI1@16  @229
+
 VarBstrFromUI2 = _VarBstrFromUI2@16  @230
 VarBstrFromUI4 = _VarBstrFromUI4@16  @231
@@ -254,6 +283,14 @@
 LPSAFEARRAY_Marshal = _LPSAFEARRAY_Marshal@0  @296
 LPSAFEARRAY_Unmarshal = _LPSAFEARRAY_Unmarshal@0  @297
+
+  VarCyMulI4               = _VarCyMulI4@16                    @304
+
+  VarBstrCat               = _VarBstrCat@12                    @313
+  VarBstrCmp               = _VarBstrCmp@16                    @314
+  VarCat                   = _VarCat@12                        @318
+
 DllRegisterServer = _OLEAUT32_DllRegisterServer@0  @320
 DllUnregisterServer = _OLEAUT32_DllUnregisterServer@0  @321
+
 VarDateFromUdate = _VarDateFromUdate@12  @330
 VarUdateFromDate = _VarUdateFromDate@16  @331
@@ -279,4 +316,5 @@
 UserMSG_free_inst = _UserMSG_free_inst@0  @398
 UserMSG_free_local = _UserMSG_free_local@0  @399
+
 DllCanUnloadNow = _OLEAUT32_DllCanUnloadNow@0  @410
 SafeArrayCreateVector = _SafeArrayCreateVector@12  @411
@@ -303,66 +341,3 @@
 SafeArrayAllocDescriptorEx = _SafeArrayAllocDescriptorEx@12 @429
 
-;430 stub SafeArrayCreateEx
-;431 stub SafeArrayCreateVectorEx
-;432 stub SafeArrayGetIID
-;433 stub SafeArrayGetRecordInfo
-;434 stub SafeArraySetIID
-;435 stub SafeArraySetRecordInfo
-;436 stub VarAbs ; stdcall (ptr ptr)
-;437 stub VarAdd ; stdcall (ptr ptr ptr)
-;438 stub VarAnd ; stdcall (ptr ptr ptr)
-VarBstrCat          = _VarBstrCat@12                    @439
-VarBstrCmp          = _VarBstrCmp@16                    @440
-VarCat              = _VarCat@12                        @441
-
-;442 stub VarCmp ; stdcall (ptr ptr long long)
-;443 stub VarCyAbs
-;444 stub VarCyAdd
-;445 stub VarCyCmp
-;446 stub VarCyCmpR8
-;447 stub VarCyFix
-;448 stub VarCyInt
-;449 stub VarCyMul
-;450 stub VarCyMulI4
-;451 stub VarCyNeg
-;452 stub VarCyRound
-;453 stub VarCySub
-;454 stub VarDateFromUdateEx ; stdcall (ptr long long ptr)
-;455 stub VarDecAbs ; stdcall (ptr ptr)
-;456 stub VarDecAdd ; stdcall (ptr ptr ptr)
-;457 stub VarDecCmp ; stdcall (ptr ptr)
-;458 stub VarDecCmpR8 ; stdcall (ptr double)
-;459 stub VarDecDiv ; stdcall (ptr ptr ptr)
-;460 stub VarDecFix ; stdcall (ptr ptr)
-;461 stub VarDecInt ; stdcall (ptr ptr)
-;462 stub VarDecMul ; stdcall (ptr ptr ptr)
-;463 stub VarDecNeg ; stdcall (ptr ptr)
-;464 stub VarDecRound ; stdcall (ptr long ptr)
-;465 stub VarDecSub ; stdcall (ptr ptr ptr)
-;466 stub VarDiv ; stdcall (ptr ptr ptr)
-;467 stub VarEqv ; stdcall (ptr ptr ptr)
-;468 stub VarFix ; stdcall (ptr ptr)
-;469 stub VarFormat ; stdcall (ptr ptr long long long ptr)
-;470 stub VarFormatCurrency ; stdcall (ptr long long long long long ptr)
-;471 stub VarFormatDateTime ; stdcall (ptr long long ptr)
-;472 stub VarFormatFromTokens ; stdcall (ptr ptr ptr long ptr long)
-;473 stub VarFormatNumber ; stdcall (ptr long long long long long ptr)
-;474 stub VarFormatPercent ; stdcall (ptr long long long long long ptr)
-;475 stub VarIdiv ; stdcall (ptr ptr ptr)
-;476 stub VarImp ; stdcall (ptr ptr ptr)
-;477 stub VarInt ; stdcall (ptr ptr)
-;478 stub VarMod ; stdcall (ptr ptr ptr)
-;479 stub VarMonthName ; stdcall (long long long ptr)
-;480 stub VarMul ; stdcall (ptr ptr ptr)
-;481 stub VarNeg ; stdcall (ptr ptr)
-;482 stub VarNot ; stdcall (ptr ptr)
-;483 stub VarOr ; stdcall (ptr ptr ptr)
-;484 stub VarPow ; stdcall (ptr ptr ptr)
-;485 stub VarR4CmpR8
-;486 stub VarR8Pow ; stdcall (double double ptr)
-;487 stub VarR8Round ; stdcall (double long ptr)
-;488 stub VarRound ; stdcall (ptr long ptr)
-;489 stub VarSub ; stdcall (ptr ptr ptr)
-;490 stub VarTokenizeFormatString ; stdcall (ptr ptr long long long long ptr)
-;491 stub VarWeekdayName ; stdcall (long long long long ptr)
-;492 stub VarXor ; stdcall (ptr ptr ptr)
+
Index: trunk/src/oleaut32/oleaut32dbg.def
===================================================================
--- trunk/src/oleaut32/oleaut32dbg.def	(revision 9394)
+++ trunk/src/oleaut32/oleaut32dbg.def	(revision 9400)
@@ -1,3 +1,3 @@
-;/* $Id: oleaut32dbg.def,v 1.2 2002-02-15 15:23:43 sandervl Exp $ */
+;/* $Id: oleaut32dbg.def,v 1.3 2002-11-12 17:07:46 sandervl Exp $ */
 LIBRARY OLAUTOS2 INITINSTANCE
 DESCRIPTION 'Odin32 System DLL - OleAut32'
@@ -68,94 +68,120 @@
 VarR4FromUI1 = _DbgVarR4FromUI1@8  @68
 VarR4FromI2 = _DbgVarR4FromI2@8  @69
-VarR4FromI4 = _DbgVarR4FromI4@8  @70
-VarR4FromR8 = _DbgVarR4FromR8@12  @71
-VarR4FromCy = _DbgVarR4FromCy@12  @72
-VarR4FromDate = _DbgVarR4FromDate@12  @73
-VarR4FromStr = _DbgVarR4FromStr@16  @74
-VarR4FromDisp = _DbgVarR4FromDisp@12  @75
-VarR4FromBool = _DbgVarR4FromBool@8  @76
-VarR8FromUI1 = _DbgVarR8FromUI1@8  @78
-VarR8FromI2 = _DbgVarR8FromI2@8  @79
-VarR8FromI4 = _DbgVarR8FromI4@8  @80
-VarR8FromR4 = _DbgVarR8FromR4@8  @81
-VarR8FromCy = _DbgVarR8FromCy@12  @82
-VarR8FromDate = _DbgVarR8FromDate@12  @83
-VarR8FromStr = _DbgVarR8FromStr@16  @84
-VarR8FromDisp = _DbgVarR8FromDisp@12  @85
-VarR8FromBool = _DbgVarR8FromBool@8  @86
-VarDateFromUI1 = _DbgVarDateFromUI1@8  @88
-VarDateFromI2 = _DbgVarDateFromI2@8  @89
-VarDateFromI4 = _DbgVarDateFromI4@8  @90
-VarDateFromR4 = _DbgVarDateFromR4@8  @91
-VarDateFromR8 = _DbgVarDateFromR8@12  @92
-VarDateFromCy = _DbgVarDateFromCy@12  @93
-VarDateFromStr = _DbgVarDateFromStr@16  @94
-VarDateFromDisp = _DbgVarDateFromDisp@12  @95
-VarDateFromBool = _DbgVarDateFromBool@8  @96
-VarCyFromUI1 = _DbgVarCyFromUI1@8  @98
-VarCyFromI2 = _DbgVarCyFromI2@8  @99
-VarCyFromI4 = _DbgVarCyFromI4@8  @100
-VarCyFromR4 = _DbgVarCyFromR4@8  @101
-VarCyFromR8 = _DbgVarCyFromR8@12  @102
-VarCyFromDate = _DbgVarCyFromDate@12  @103
-VarCyFromStr = _DbgVarCyFromStr@16  @104
-VarCyFromDisp = _DbgVarCyFromDisp@12  @105
-VarCyFromBool = _DbgVarCyFromBool@8  @106
-VarBstrFromUI1 = _DbgVarBstrFromUI1@16  @108
-VarBstrFromI2 = _DbgVarBstrFromI2@16  @109
-VarBstrFromI4 = _DbgVarBstrFromI4@16  @110
-VarBstrFromR4 = _DbgVarBstrFromR4@16  @111
-VarBstrFromR8 = _DbgVarBstrFromR8@20  @112
-VarBstrFromCy = _DbgVarBstrFromCy@20  @113
-VarBstrFromDate = _DbgVarBstrFromDate@20  @114
-VarBstrFromDisp = _DbgVarBstrFromDisp@16  @115
-VarBstrFromBool = _DbgVarBstrFromBool@16  @116
-VarBoolFromUI1 = _DbgVarBoolFromUI1@8  @118
-VarBoolFromI2 = _DbgVarBoolFromI2@8  @119
-VarBoolFromI4 = _DbgVarBoolFromI4@8  @120
-VarBoolFromR4 = _DbgVarBoolFromR4@8  @121
-VarBoolFromR8 = _DbgVarBoolFromR8@12  @122
-VarBoolFromDate = _DbgVarBoolFromDate@12  @123
-VarBoolFromCy = _DbgVarBoolFromCy@12  @124
-VarBoolFromStr = _DbgVarBoolFromStr@16  @125
-VarBoolFromDisp = _DbgVarBoolFromDisp@12  @126
-VarUI1FromI2 = _DbgVarUI1FromI2@8  @130
-VarUI1FromI4 = _DbgVarUI1FromI4@8  @131
-VarUI1FromR4 = _DbgVarUI1FromR4@8  @132
-VarUI1FromR8 = _DbgVarUI1FromR8@12  @133
-VarUI1FromCy = _DbgVarUI1FromCy@12  @134
-VarUI1FromDate = _DbgVarUI1FromDate@12  @135
-VarUI1FromStr = _DbgVarUI1FromStr@16  @136
-VarUI1FromDisp = _DbgVarUI1FromDisp@12  @137
-VarUI1FromBool = _DbgVarUI1FromBool@8  @138
-DispCallFunc = _DbgDispCallFunc@32  @146
-VariantChangeTypeEx = _DbgVariantChangeTypeEx@20  @147
-SafeArrayPtrOfIndex = _DbgSafeArrayPtrOfIndex@12  @148
-SysStringByteLen = _DbgSysStringByteLen@4  @149
-SysAllocStringByteLen = _DbgSysAllocStringByteLen@8  @150
-CreateTypeLib = _DbgCreateTypeLib@12  @160
-LoadTypeLib = _DbgLoadTypeLib@8  @161
-LoadRegTypeLib = _DbgLoadRegTypeLib@20  @162
-RegisterTypeLib = _DbgRegisterTypeLib@12  @163
-QueryPathOfRegTypeLib = _DbgQueryPathOfRegTypeLib@20  @164
-LHashValOfNameSys = _DbgLHashValOfNameSys@12  @165
-LHashValOfNameSysA = _DbgLHashValOfNameSysA@12  @166
-OaBuildVersion = _DbgOaBuildVersion@0  @170
-ClearCustData = _DbgClearCustData@4  @171
-CreateTypeLib2 = _DbgCreateTypeLib2@12  @180
-LoadTypeLibEx = _DbgLoadTypeLibEx@12  @183
-SystemTimeToVariantTime = _DbgSystemTimeToVariantTime@8  @184
-VariantTimeToSystemTime = _DbgVariantTimeToSystemTime@12  @185
-UnRegisterTypeLib = _DbgUnRegisterTypeLib@20  @186
-VarDecFromUI1 = _DbgVarDecFromUI1@8  @190
-VarDecFromI2 = _DbgVarDecFromI2@8  @191
-VarDecFromI4 = _DbgVarDecFromI4@8  @192
-VarDecFromR4 = _DbgVarDecFromR4@8  @193
-VarDecFromR8 = _DbgVarDecFromR8@12  @194
-VarDecFromDate = _DbgVarDecFromDate@12  @195
-VarDecFromCy = _DbgVarDecFromCy@12  @196
-VarDecFromStr = _DbgVarDecFromStr@16  @197
-VarDecFromDisp = _DbgVarDecFromDisp@12  @198
-VarDecFromBool = _DbgVarDecFromBool@8  @199
+
+  VarR4FromI4                 = _DbgVarR4FromI4@8                  @70
+  VarR4FromR8                 = _DbgVarR4FromR8@12                 @71
+  VarR4FromCy                 = _DbgVarR4FromCy@12                 @72
+  VarR4FromDate               = _DbgVarR4FromDate@12               @73
+  VarR4FromStr                = _DbgVarR4FromStr@16                @74
+  VarR4FromDisp               = _DbgVarR4FromDisp@12               @75
+  VarR4FromBool               = _DbgVarR4FromBool@8                @76
+  SafeArrayGetVartype         = _DbgSafeArrayGetVartype@8          @77
+  VarR8FromUI1                = _DbgVarR8FromUI1@8                 @78
+  VarR8FromI2                 = _DbgVarR8FromI2@8                  @79
+
+  VarR8FromI4                 = _DbgVarR8FromI4@8                  @80
+  VarR8FromR4                 = _DbgVarR8FromR4@8                  @81
+  VarR8FromCy                 = _DbgVarR8FromCy@12                 @82
+  VarR8FromDate               = _DbgVarR8FromDate@12               @83
+  VarR8FromStr                = _DbgVarR8FromStr@16                @84
+  VarR8FromDisp               = _DbgVarR8FromDisp@12               @85
+  VarR8FromBool               = _DbgVarR8FromBool@8                @86
+  VarFormat                   = _DbgVarFormat@24                   @87
+  VarDateFromUI1              = _DbgVarDateFromUI1@8               @88
+  VarDateFromI2               = _DbgVarDateFromI2@8                @89
+
+  VarDateFromI4               = _DbgVarDateFromI4@8                @90
+  VarDateFromR4               = _DbgVarDateFromR4@8                @91
+  VarDateFromR8               = _DbgVarDateFromR8@12               @92
+  VarDateFromCy               = _DbgVarDateFromCy@12               @93
+  VarDateFromStr              = _DbgVarDateFromStr@16              @94
+  VarDateFromDisp             = _DbgVarDateFromDisp@12             @95
+  VarDateFromBool             = _DbgVarDateFromBool@8              @96
+  VarFormatDateTime           = _DbgVarFormatDateTime@16           @97
+  VarCyFromUI1                = _DbgVarCyFromUI1@8                 @98
+  VarCyFromI2                 = _DbgVarCyFromI2@8                  @99
+
+  VarCyFromI4                 = _DbgVarCyFromI4@8                  @100
+  VarCyFromR4                 = _DbgVarCyFromR4@8                  @101
+  VarCyFromR8                 = _DbgVarCyFromR8@12                 @102
+  VarCyFromDate               = _DbgVarCyFromDate@12               @103
+  VarCyFromStr                = _DbgVarCyFromStr@16                @104
+  VarCyFromDisp               = _DbgVarCyFromDisp@12               @105
+  VarCyFromBool               = _DbgVarCyFromBool@8                @106
+;;  VarFormatNumber             = _DbgVarFormatNumber@28             @107
+  VarBstrFromUI1              = _DbgVarBstrFromUI1@16              @108
+  VarBstrFromI2               = _DbgVarBstrFromI2@16               @109
+
+  VarBstrFromI4               = _DbgVarBstrFromI4@16               @110
+  VarBstrFromR4               = _DbgVarBstrFromR4@16               @111
+  VarBstrFromR8               = _DbgVarBstrFromR8@20               @112
+  VarBstrFromCy               = _DbgVarBstrFromCy@20               @113
+  VarBstrFromDate             = _DbgVarBstrFromDate@20             @114
+  VarBstrFromDisp             = _DbgVarBstrFromDisp@16             @115
+  VarBstrFromBool             = _DbgVarBstrFromBool@16             @116
+;;  VarFormatPercent            = _DbgVarFormatPercent@28            @117
+  VarBoolFromUI1              = _DbgVarBoolFromUI1@8               @118
+  VarBoolFromI2               = _DbgVarBoolFromI2@8                @119
+
+  VarBoolFromI4               = _DbgVarBoolFromI4@8                @120
+  VarBoolFromR4               = _DbgVarBoolFromR4@8                @121
+  VarBoolFromR8               = _DbgVarBoolFromR8@12               @122
+  VarBoolFromDate             = _DbgVarBoolFromDate@12             @123
+  VarBoolFromCy               = _DbgVarBoolFromCy@12               @124
+  VarBoolFromStr              = _DbgVarBoolFromStr@16              @125
+  VarBoolFromDisp             = _DbgVarBoolFromDisp@12             @126
+  VarFormatCurrency           = _DbgVarFormatCurrency@28           @127
+
+  VarUI1FromI2                = _DbgVarUI1FromI2@8                 @130
+  VarUI1FromI4                = _DbgVarUI1FromI4@8                 @131
+  VarUI1FromR4                = _DbgVarUI1FromR4@8                 @132
+  VarUI1FromR8                = _DbgVarUI1FromR8@12                @133
+  VarUI1FromCy                = _DbgVarUI1FromCy@12                @134
+  VarUI1FromDate              = _DbgVarUI1FromDate@12              @135
+  VarUI1FromStr               = _DbgVarUI1FromStr@16               @136
+  VarUI1FromDisp              = _DbgVarUI1FromDisp@12              @137
+  VarUI1FromBool              = _DbgVarUI1FromBool@8               @138
+  VarFormatFromTokens         = _DbgVarFormatFromTokens@24         @139
+
+  VarTokenizeFormatString     = _DbgVarTokenizeFormatString@28     @140
+  VarAnd                      = _DbgVarAnd@12                      @142
+
+  DispCallFunc                = _DbgDispCallFunc@32                @146
+  VariantChangeTypeEx         = _DbgVariantChangeTypeEx@20         @147
+  SafeArrayPtrOfIndex         = _DbgSafeArrayPtrOfIndex@12         @148
+  SysStringByteLen            = _DbgSysStringByteLen@4             @149
+
+  SysAllocStringByteLen       = _DbgSysAllocStringByteLen@8        @150
+
+  CreateTypeLib               = _DbgCreateTypeLib@12               @160
+  LoadTypeLib                 = _DbgLoadTypeLib@8                  @161
+  LoadRegTypeLib              = _DbgLoadRegTypeLib@20              @162
+  RegisterTypeLib             = _DbgRegisterTypeLib@12             @163
+  QueryPathOfRegTypeLib       = _DbgQueryPathOfRegTypeLib@20       @164
+  LHashValOfNameSys           = _DbgLHashValOfNameSys@12           @165
+  LHashValOfNameSysA          = _DbgLHashValOfNameSysA@12          @166
+
+  OaBuildVersion              = _DbgOaBuildVersion@0               @170
+  ClearCustData               = _DbgClearCustData@4                @171
+  VarNot                      = _DbgVarNot@8                       @174
+  VarCmp                      = _DbgVarCmp@16                      @176
+
+  CreateTypeLib2              = _DbgCreateTypeLib2@12              @180
+  LoadTypeLibEx               = _DbgLoadTypeLibEx@12               @183
+  SystemTimeToVariantTime     = _DbgSystemTimeToVariantTime@8      @184
+  VariantTimeToSystemTime     = _DbgVariantTimeToSystemTime@12     @185
+  UnRegisterTypeLib           = _DbgUnRegisterTypeLib@20           @186
+
+  VarDecFromUI1               = _DbgVarDecFromUI1@8                @190
+  VarDecFromI2                = _DbgVarDecFromI2@8                 @191
+  VarDecFromI4                = _DbgVarDecFromI4@8                 @192
+  VarDecFromR4                = _DbgVarDecFromR4@8                 @193
+  VarDecFromR8                = _DbgVarDecFromR8@12                @194
+  VarDecFromDate              = _DbgVarDecFromDate@12              @195
+  VarDecFromCy                = _DbgVarDecFromCy@12                @196
+  VarDecFromStr               = _DbgVarDecFromStr@16               @197
+  VarDecFromDisp              = _DbgVarDecFromDisp@12              @198
+  VarDecFromBool              = _DbgVarDecFromBool@8               @199
+
 GetErrorInfo = _GetErrorInfo@8  @200
 SetErrorInfo = _SetErrorInfo@8  @201
@@ -254,4 +280,11 @@
 LPSAFEARRAY_Marshal = _DbgLPSAFEARRAY_Marshal@0  @296
 LPSAFEARRAY_Unmarshal = _DbgLPSAFEARRAY_Unmarshal@0  @297
+
+  VarCyMulI4               = _DbgVarCyMulI4@16                    @304
+
+  VarBstrCat               = _DbgVarBstrCat@12                    @313
+  VarBstrCmp               = _DbgVarBstrCmp@16                    @314
+  VarCat                   = _DbgVarCat@12                        @318
+
 DllRegisterServer = _DbgOLEAUT32_DllRegisterServer@0  @320
 DllUnregisterServer = _DbgOLEAUT32_DllUnregisterServer@0  @321
@@ -303,66 +336,2 @@
 SafeArrayAllocDescriptorEx = _DbgSafeArrayAllocDescriptorEx@12 @429
 
-;430 stub SafeArrayCreateEx
-;431 stub SafeArrayCreateVectorEx
-;432 stub SafeArrayGetIID
-;433 stub SafeArrayGetRecordInfo
-;434 stub SafeArraySetIID
-;435 stub SafeArraySetRecordInfo
-;436 stub VarAbs ; stdcall (ptr ptr)
-;437 stub VarAdd ; stdcall (ptr ptr ptr)
-;438 stub VarAnd ; stdcall (ptr ptr ptr)
-VarBstrCat          = _DbgVarBstrCat@12                    @439
-VarBstrCmp          = _DbgVarBstrCmp@16                    @440
-VarCat              = _DbgVarCat@12                        @441
-
-;442 stub VarCmp ; stdcall (ptr ptr long long)
-;443 stub VarCyAbs
-;444 stub VarCyAdd
-;445 stub VarCyCmp
-;446 stub VarCyCmpR8
-;447 stub VarCyFix
-;448 stub VarCyInt
-;449 stub VarCyMul
-;450 stub VarCyMulI4
-;451 stub VarCyNeg
-;452 stub VarCyRound
-;453 stub VarCySub
-;454 stub VarDateFromUdateEx ; stdcall (ptr long long ptr)
-;455 stub VarDecAbs ; stdcall (ptr ptr)
-;456 stub VarDecAdd ; stdcall (ptr ptr ptr)
-;457 stub VarDecCmp ; stdcall (ptr ptr)
-;458 stub VarDecCmpR8 ; stdcall (ptr double)
-;459 stub VarDecDiv ; stdcall (ptr ptr ptr)
-;460 stub VarDecFix ; stdcall (ptr ptr)
-;461 stub VarDecInt ; stdcall (ptr ptr)
-;462 stub VarDecMul ; stdcall (ptr ptr ptr)
-;463 stub VarDecNeg ; stdcall (ptr ptr)
-;464 stub VarDecRound ; stdcall (ptr long ptr)
-;465 stub VarDecSub ; stdcall (ptr ptr ptr)
-;466 stub VarDiv ; stdcall (ptr ptr ptr)
-;467 stub VarEqv ; stdcall (ptr ptr ptr)
-;468 stub VarFix ; stdcall (ptr ptr)
-;469 stub VarFormat ; stdcall (ptr ptr long long long ptr)
-;470 stub VarFormatCurrency ; stdcall (ptr long long long long long ptr)
-;471 stub VarFormatDateTime ; stdcall (ptr long long ptr)
-;472 stub VarFormatFromTokens ; stdcall (ptr ptr ptr long ptr long)
-;473 stub VarFormatNumber ; stdcall (ptr long long long long long ptr)
-;474 stub VarFormatPercent ; stdcall (ptr long long long long long ptr)
-;475 stub VarIdiv ; stdcall (ptr ptr ptr)
-;476 stub VarImp ; stdcall (ptr ptr ptr)
-;477 stub VarInt ; stdcall (ptr ptr)
-;478 stub VarMod ; stdcall (ptr ptr ptr)
-;479 stub VarMonthName ; stdcall (long long long ptr)
-;480 stub VarMul ; stdcall (ptr ptr ptr)
-;481 stub VarNeg ; stdcall (ptr ptr)
-;482 stub VarNot ; stdcall (ptr ptr)
-;483 stub VarOr ; stdcall (ptr ptr ptr)
-;484 stub VarPow ; stdcall (ptr ptr ptr)
-;485 stub VarR4CmpR8
-;486 stub VarR8Pow ; stdcall (double double ptr)
-;487 stub VarR8Round ; stdcall (double long ptr)
-;488 stub VarRound ; stdcall (ptr long ptr)
-;489 stub VarSub ; stdcall (ptr ptr ptr)
-;490 stub VarTokenizeFormatString ; stdcall (ptr ptr long long long long ptr)
-;491 stub VarWeekdayName ; stdcall (long long long long ptr)
-;492 stub VarXor ; stdcall (ptr ptr ptr)
Index: trunk/src/oleaut32/olefont.c
===================================================================
--- trunk/src/oleaut32/olefont.c	(revision 9394)
+++ trunk/src/oleaut32/olefont.c	(revision 9400)
@@ -25,5 +25,4 @@
 #include "oleaut32.h"
 #endif
-
 #include <assert.h>
 #include <string.h>
@@ -59,5 +58,5 @@
 {
   /*
-   * This class supports many interfaces. IUnknown, IFont, 
+   * This class supports many interfaces. IUnknown, IFont,
    * IDispatch, IDispFont IPersistStream and IConnectionPointContainer.
    * The first two are supported by the first vtable, the next two are
@@ -98,5 +97,5 @@
 
 /*
- * Here, I define utility macros to help with the casting of the 
+ * Here, I define utility macros to help with the casting of the
  * "this" parameter.
  * There is a version to accomodate all of the VTables implemented
@@ -104,7 +103,7 @@
  */
 #define _ICOM_THIS(class,name) class* this = (class*)name;
-#define _ICOM_THIS_From_IDispatch(class, name) class* this = (class*)(((char*)name)-sizeof(void*)); 
-#define _ICOM_THIS_From_IPersistStream(class, name) class* this = (class*)(((char*)name)-2*sizeof(void*)); 
-#define _ICOM_THIS_From_IConnectionPointContainer(class, name) class* this = (class*)(((char*)name)-3*sizeof(void*)); 
+#define _ICOM_THIS_From_IDispatch(class, name) class* this = (class*)(((char*)name)-sizeof(void*));
+#define _ICOM_THIS_From_IPersistStream(class, name) class* this = (class*)(((char*)name)-2*sizeof(void*));
+#define _ICOM_THIS_From_IConnectionPointContainer(class, name) class* this = (class*)(((char*)name)-3*sizeof(void*));
 
 
@@ -147,30 +146,30 @@
  * interface
  */
-static HRESULT WINAPI OLEFontImpl_IDispatch_QueryInterface(IDispatch* iface, 
-						    REFIID     riid, 
+static HRESULT WINAPI OLEFontImpl_IDispatch_QueryInterface(IDispatch* iface,
+						    REFIID     riid,
 						    VOID**     ppvoid);
 static ULONG   WINAPI OLEFontImpl_IDispatch_AddRef(IDispatch* iface);
 static ULONG   WINAPI OLEFontImpl_IDispatch_Release(IDispatch* iface);
-static HRESULT WINAPI OLEFontImpl_GetTypeInfoCount(IDispatch*    iface, 
+static HRESULT WINAPI OLEFontImpl_GetTypeInfoCount(IDispatch*    iface,
 					           unsigned int* pctinfo);
-static HRESULT WINAPI OLEFontImpl_GetTypeInfo(IDispatch*  iface, 
+static HRESULT WINAPI OLEFontImpl_GetTypeInfo(IDispatch*  iface,
 				       	      UINT      iTInfo,
-				              LCID        lcid, 
+				              LCID        lcid,
 				              ITypeInfo** ppTInfo);
 static HRESULT WINAPI OLEFontImpl_GetIDsOfNames(IDispatch*  iface,
-					        REFIID      riid, 
-					        LPOLESTR* rgszNames, 
-					        UINT      cNames, 
+					        REFIID      riid,
+					        LPOLESTR* rgszNames,
+					        UINT      cNames,
 					        LCID        lcid,
 					        DISPID*     rgDispId);
 static HRESULT WINAPI OLEFontImpl_Invoke(IDispatch*  iface,
-				         DISPID      dispIdMember, 
-				         REFIID      riid, 
-				         LCID        lcid, 
+				         DISPID      dispIdMember,
+				         REFIID      riid,
+				         LCID        lcid,
 				         WORD        wFlags,
 				         DISPPARAMS* pDispParams,
-				         VARIANT*    pVarResult, 
+				         VARIANT*    pVarResult,
 				         EXCEPINFO*  pExepInfo,
-				         UINT*     puArgErr); 
+				         UINT*     puArgErr);
 
 /***********************************************************************
@@ -178,10 +177,10 @@
  * interface
  */
-static HRESULT WINAPI OLEFontImpl_IPersistStream_QueryInterface(IPersistStream* iface, 
-						    REFIID     riid, 
+static HRESULT WINAPI OLEFontImpl_IPersistStream_QueryInterface(IPersistStream* iface,
+						    REFIID     riid,
 						    VOID**     ppvoid);
 static ULONG   WINAPI OLEFontImpl_IPersistStream_AddRef(IPersistStream* iface);
 static ULONG   WINAPI OLEFontImpl_IPersistStream_Release(IPersistStream* iface);
-static HRESULT WINAPI OLEFontImpl_GetClassID(IPersistStream* iface, 
+static HRESULT WINAPI OLEFontImpl_GetClassID(IPersistStream* iface,
 					     CLSID*                pClassID);
 static HRESULT WINAPI OLEFontImpl_IsDirty(IPersistStream*  iface);
@@ -190,7 +189,7 @@
 static HRESULT WINAPI OLEFontImpl_Save(IPersistStream*  iface,
 				       IStream*         pOutStream,
-				       BOOL             fClearDirty); 
+				       BOOL             fClearDirty);
 static HRESULT WINAPI OLEFontImpl_GetSizeMax(IPersistStream*  iface,
-					     ULARGE_INTEGER*  pcbSize); 
+					     ULARGE_INTEGER*  pcbSize);
 
 /***********************************************************************
@@ -199,6 +198,6 @@
  */
 static HRESULT WINAPI OLEFontImpl_IConnectionPointContainer_QueryInterface(
-					    IConnectionPointContainer* iface, 
-					    REFIID     riid, 
+					    IConnectionPointContainer* iface,
+					    REFIID     riid,
 					    VOID**     ppvoid);
 static ULONG   WINAPI OLEFontImpl_IConnectionPointContainer_AddRef(
@@ -240,5 +239,5 @@
   OLEFontImpl_put_Charset,
   OLEFontImpl_get_hFont,
-  OLEFontImpl_Clone, 
+  OLEFontImpl_Clone,
   OLEFontImpl_IsEqual,
   OLEFontImpl_SetRatio,
@@ -347,5 +346,5 @@
 
   IConnectionPoint_EnumConnections(this->pCP, &pEnum);
-  
+
   while(IEnumConnections_Next(pEnum, 1, &CD, NULL) == S_OK) {
     IPropertyNotifySink *sink;
@@ -359,5 +358,5 @@
   return;
 }
-  
+
 /************************************************************************
  * OLEFontImpl_Construct
@@ -380,5 +379,5 @@
   if (newObject==0)
     return newObject;
-  
+
   /*
    * Initialize the virtual function table.
@@ -388,7 +387,7 @@
   newObject->lpvtbl3 = &OLEFontImpl_IPersistStream_VTable;
   newObject->lpvtbl4 = &OLEFontImpl_IConnectionPointContainer_VTable;
-  
-  /*
-   * Start with one reference count. The caller of this function 
+
+  /*
+   * Start with one reference count. The caller of this function
    * must release the interface pointer when it is done.
    */
@@ -402,5 +401,5 @@
   newObject->description.cbSizeofstruct = sizeof(FONTDESC);
   newObject->description.lpstrName = HeapAlloc(GetProcessHeap(),
-					       0, 
+					       0,
 					       (lstrlenW(fontDesc->lpstrName)+1) * sizeof(WCHAR));
   strcpyW(newObject->description.lpstrName, fontDesc->lpstrName);
@@ -464,39 +463,39 @@
   if ( (this==0) || (ppvObject==0) )
     return E_INVALIDARG;
-  
+
   /*
    * Initialize the return parameter.
    */
   *ppvObject = 0;
-  
+
   /*
    * Compare the riid with the interface IDs implemented by this object.
    */
-  if (memcmp(&IID_IUnknown, riid, sizeof(IID_IUnknown)) == 0) 
+  if (memcmp(&IID_IUnknown, riid, sizeof(IID_IUnknown)) == 0)
   {
     *ppvObject = (IFont*)this;
   }
-  else if (memcmp(&IID_IFont, riid, sizeof(IID_IFont)) == 0) 
+  else if (memcmp(&IID_IFont, riid, sizeof(IID_IFont)) == 0)
   {
     *ppvObject = (IFont*)this;
   }
-  else if (memcmp(&IID_IDispatch, riid, sizeof(IID_IDispatch)) == 0) 
+  else if (memcmp(&IID_IDispatch, riid, sizeof(IID_IDispatch)) == 0)
   {
     *ppvObject = (IDispatch*)&(this->lpvtbl2);
   }
-  else if (memcmp(&IID_IFontDisp, riid, sizeof(IID_IFontDisp)) == 0) 
+  else if (memcmp(&IID_IFontDisp, riid, sizeof(IID_IFontDisp)) == 0)
   {
     *ppvObject = (IDispatch*)&(this->lpvtbl2);
   }
-  else if (memcmp(&IID_IPersistStream, riid, sizeof(IID_IPersistStream)) == 0) 
+  else if (memcmp(&IID_IPersistStream, riid, sizeof(IID_IPersistStream)) == 0)
   {
     *ppvObject = (IPersistStream*)&(this->lpvtbl3);
   }
   else if (memcmp(&IID_IConnectionPointContainer, riid,
-		  sizeof(IID_IConnectionPointContainer)) == 0) 
+		  sizeof(IID_IConnectionPointContainer)) == 0)
   {
     *ppvObject = (IPersistStream*)&(this->lpvtbl4);
   }
-  
+
   /*
    * Check that we obtained an interface.
@@ -507,5 +506,5 @@
     return E_NOINTERFACE;
   }
-  
+
   /*
    * Query Interface always increases the reference count by one when it is
@@ -514,7 +513,7 @@
   OLEFontImpl_AddRef((IFont*)this);
 
-  return S_OK;;
-}
-        
+  return S_OK;
+}
+
 /************************************************************************
  * OLEFontImpl_AddRef (IUnknown)
@@ -522,5 +521,5 @@
  * See Windows documentation for more details on IUnknown methods.
  */
-ULONG WINAPI OLEFontImpl_AddRef( 
+ULONG WINAPI OLEFontImpl_AddRef(
   IFont* iface)
 {
@@ -531,5 +530,5 @@
   return this->ref;
 }
-        
+
 /************************************************************************
  * OLEFontImpl_Release (IUnknown)
@@ -537,5 +536,5 @@
  * See Windows documentation for more details on IUnknown methods.
  */
-ULONG WINAPI OLEFontImpl_Release( 
+ULONG WINAPI OLEFontImpl_Release(
       IFont* iface)
 {
@@ -557,8 +556,8 @@
     return 0;
   }
-  
+
   return this->ref;
 }
-        
+
 /************************************************************************
  * OLEFontImpl_get_Name (IFont)
@@ -567,5 +566,5 @@
  */
 static HRESULT WINAPI OLEFontImpl_get_Name(
-  IFont*  iface, 
+  IFont*  iface,
   BSTR* pname)
 {
@@ -592,5 +591,5 @@
  */
 static HRESULT WINAPI OLEFontImpl_put_Name(
-  IFont* iface, 
+  IFont* iface,
   BSTR name)
 {
@@ -601,5 +600,5 @@
   {
     this->description.lpstrName = HeapAlloc(GetProcessHeap(),
-					    0, 
+					    0,
 					    (lstrlenW(name)+1) * sizeof(WCHAR));
   }
@@ -607,5 +606,5 @@
   {
     this->description.lpstrName = HeapReAlloc(GetProcessHeap(),
-					      0, 
+					      0,
 					      this->description.lpstrName,
 					      (lstrlenW(name)+1) * sizeof(WCHAR));
@@ -627,5 +626,5 @@
  */
 static HRESULT WINAPI OLEFontImpl_get_Size(
-  IFont* iface, 
+  IFont* iface,
   CY*    psize)
 {
@@ -651,5 +650,5 @@
  */
 static HRESULT WINAPI OLEFontImpl_put_Size(
-  IFont* iface, 
+  IFont* iface,
   CY     size)
 {
@@ -669,5 +668,5 @@
  */
 static HRESULT WINAPI OLEFontImpl_get_Bold(
-  IFont*  iface, 
+  IFont*  iface,
   BOOL* pbold)
 {
@@ -708,5 +707,5 @@
  */
 static HRESULT WINAPI OLEFontImpl_get_Italic(
-  IFont*  iface, 
+  IFont*  iface,
   BOOL* pitalic)
 {
@@ -730,5 +729,5 @@
  */
 static HRESULT WINAPI OLEFontImpl_put_Italic(
-  IFont* iface, 
+  IFont* iface,
   BOOL italic)
 {
@@ -748,5 +747,5 @@
  */
 static HRESULT WINAPI OLEFontImpl_get_Underline(
-  IFont*  iface, 
+  IFont*  iface,
   BOOL* punderline)
 {
@@ -789,5 +788,5 @@
  */
 static HRESULT WINAPI OLEFontImpl_get_Strikethrough(
-  IFont*  iface, 
+  IFont*  iface,
   BOOL* pstrikethrough)
 {
@@ -812,5 +811,5 @@
  */
 static HRESULT WINAPI OLEFontImpl_put_Strikethrough(
- IFont* iface, 
+ IFont* iface,
  BOOL strikethrough)
 {
@@ -830,5 +829,5 @@
  */
 static HRESULT WINAPI OLEFontImpl_get_Weight(
-  IFont* iface, 
+  IFont* iface,
   short* pweight)
 {
@@ -853,5 +852,5 @@
  */
 static HRESULT WINAPI OLEFontImpl_put_Weight(
-  IFont* iface, 
+  IFont* iface,
   short  weight)
 {
@@ -871,5 +870,5 @@
  */
 static HRESULT WINAPI OLEFontImpl_get_Charset(
-  IFont* iface, 
+  IFont* iface,
   short* pcharset)
 {
@@ -894,5 +893,5 @@
  */
 static HRESULT WINAPI OLEFontImpl_put_Charset(
-  IFont* iface, 
+  IFont* iface,
   short charset)
 {
@@ -928,5 +927,5 @@
     INT      fontHeight;
     CY       cySize;
-    
+
     /*
      * The height of the font returned by the get_Size property is the
@@ -959,5 +958,5 @@
 
   *phfont = this->gdiFont;
-  TRACE("Returning %08x\n", *phfont);
+  TRACE("Returning %p\n", *phfont);
   return S_OK;
 }
@@ -1001,4 +1000,5 @@
 	(1+strlenW(this->description.lpstrName))*2
   );
+  strcpyW(newObject->description.lpstrName, this->description.lpstrName);
   /* We need to clone the HFONT too. This is just cut & paste from above */
   IFont_get_Size(iface, &cySize);
@@ -1039,5 +1039,5 @@
  */
 static HRESULT WINAPI OLEFontImpl_IsEqual(
-  IFont* iface, 
+  IFont* iface,
   IFont* pFontOther)
 {
@@ -1071,5 +1071,5 @@
  */
 static HRESULT      WINAPI OLEFontImpl_QueryTextMetrics(
-  IFont*         iface, 
+  IFont*         iface,
   TEXTMETRICOLE* ptm)
 {
@@ -1084,9 +1084,9 @@
  */
 static HRESULT WINAPI OLEFontImpl_AddRefHfont(
-  IFont*  iface, 
+  IFont*  iface,
   HFONT hfont)
 {
   _ICOM_THIS(OLEFontImpl, iface);
-  TRACE("(%p)->(%08x) (lock=%ld)\n", this, hfont, this->fontLock);
+  TRACE("(%p)->(%p) (lock=%ld)\n", this, hfont, this->fontLock);
 
   if ( (hfont == 0) ||
@@ -1109,5 +1109,5 @@
 {
   _ICOM_THIS(OLEFontImpl, iface);
-  TRACE("(%p)->(%08x) (lock=%ld)\n", this, hfont, this->fontLock);
+  TRACE("(%p)->(%p) (lock=%ld)\n", this, hfont, this->fontLock);
 
   if ( (hfont == 0) ||
@@ -1123,5 +1123,5 @@
   {
     DeleteObject(this->gdiFont);
-    this->gdiFont = 0; 
+    this->gdiFont = 0;
   }
 
@@ -1139,5 +1139,5 @@
 {
   _ICOM_THIS(OLEFontImpl, iface);
-  FIXME("(%p)->(%08x): Stub\n", this, hdc);
+  FIXME("(%p)->(%p): Stub\n", this, hdc);
   return E_NOTIMPL;
 }
@@ -1190,5 +1190,5 @@
  */
 static HRESULT WINAPI OLEFontImpl_GetTypeInfoCount(
-  IDispatch*    iface, 
+  IDispatch*    iface,
   unsigned int* pctinfo)
 {
@@ -1205,7 +1205,7 @@
  */
 static HRESULT WINAPI OLEFontImpl_GetTypeInfo(
-  IDispatch*  iface, 
+  IDispatch*  iface,
   UINT      iTInfo,
-  LCID        lcid, 
+  LCID        lcid,
   ITypeInfo** ppTInfo)
 {
@@ -1223,7 +1223,7 @@
 static HRESULT WINAPI OLEFontImpl_GetIDsOfNames(
   IDispatch*  iface,
-  REFIID      riid, 
-  LPOLESTR* rgszNames, 
-  UINT      cNames, 
+  REFIID      riid,
+  LPOLESTR* rgszNames,
+  UINT      cNames,
   LCID        lcid,
   DISPID*     rgDispId)
@@ -1242,10 +1242,10 @@
 static HRESULT WINAPI OLEFontImpl_Invoke(
   IDispatch*  iface,
-  DISPID      dispIdMember, 
-  REFIID      riid, 
-  LCID        lcid, 
+  DISPID      dispIdMember,
+  REFIID      riid,
+  LCID        lcid,
   WORD        wFlags,
   DISPPARAMS* pDispParams,
-  VARIANT*    pVarResult, 
+  VARIANT*    pVarResult,
   EXCEPINFO*  pExepInfo,
   UINT*     puArgErr)
@@ -1305,5 +1305,5 @@
  */
 static HRESULT WINAPI OLEFontImpl_GetClassID(
-  IPersistStream* iface, 
+  IPersistStream* iface,
   CLSID*                pClassID)
 {
@@ -1360,5 +1360,5 @@
 
   _ICOM_THIS_From_IPersistStream(OLEFontImpl, iface);
-  
+
   /*
    * Read the version byte
@@ -1389,5 +1389,5 @@
   this->description.fStrikethrough = (bAttributes & FONTPERSIST_STRIKETHROUGH) != 0;
   this->description.fUnderline     = (bAttributes & FONTPERSIST_UNDERLINE) != 0;
-    
+
   /*
    * Weight
@@ -1428,4 +1428,8 @@
   MultiByteToWideChar( CP_ACP, 0, readBuffer, bStringSize, this->description.lpstrName, len );
   this->description.lpstrName[len] = 0;
+
+  /* Ensure use of this font causes a new one to be created @@@@ */
+  DeleteObject(this->gdiFont);
+  this->gdiFont = 0;
 
   return S_OK;
@@ -1447,5 +1451,5 @@
   BYTE  bAttributes;
   BYTE  bStringSize;
-  
+
   _ICOM_THIS_From_IPersistStream(OLEFontImpl, iface);
 
@@ -1476,5 +1480,5 @@
   if (this->description.fStrikethrough)
     bAttributes |= FONTPERSIST_STRIKETHROUGH;
-  
+
   if (this->description.fUnderline)
     bAttributes |= FONTPERSIST_UNDERLINE;
@@ -1484,5 +1488,5 @@
   if (cbWritten!=1)
     return E_FAIL;
-  
+
   /*
    * Weight
@@ -1652,5 +1656,5 @@
 } IClassFactoryImpl;
 
-static HRESULT WINAPI 
+static HRESULT WINAPI
 SFCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) {
 	ICOM_THIS(IClassFactoryImpl,iface);
Index: trunk/src/oleaut32/olepicture.c
===================================================================
--- trunk/src/oleaut32/olepicture.c	(revision 9394)
+++ trunk/src/oleaut32/olepicture.c	(revision 9400)
@@ -38,5 +38,7 @@
 #include "config.h"
 
-#include <unistd.h>
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
 #include <stdio.h>
 #include <string.h>
@@ -58,5 +60,6 @@
 #ifdef HAVE_LIBJPEG
 /* This is a hack, so jpeglib.h does not redefine INT32 and the like*/
-#define XMD_H 
+#define XMD_H
+#define UINT8 JPEG_UINT8
 #define UINT16 JPEG_UINT16
 #ifdef HAVE_JPEGLIB_H
@@ -88,5 +91,5 @@
   /* We own the object and must destroy it ourselves */
     BOOL fOwn;
-  
+
   /* Picture description */
     PICTDESC desc;
@@ -104,4 +107,8 @@
     BOOL keepOrigFormat;
     HDC	hDCCur;
+
+  /* data */
+    void* data;
+    int datalen;
 } OLEPictureImpl;
 
@@ -132,5 +139,5 @@
   HDC hdcRef;
 
-  TRACE("bitmap handle %08x\n", This->desc.u.bmp.hbitmap);
+  TRACE("bitmap handle %p\n", This->desc.u.bmp.hbitmap);
   if(GetObjectA(This->desc.u.bmp.hbitmap, sizeof(bm), &bm) != sizeof(bm)) {
     ERR("GetObject fails\n");
@@ -168,9 +175,9 @@
    * Allocate space for the object.
    */
-  newObject = HeapAlloc(GetProcessHeap(), 0, sizeof(OLEPictureImpl));
+  newObject = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(OLEPictureImpl));
 
   if (newObject==0)
     return newObject;
-  
+
   /*
    * Initialize the virtual function table.
@@ -184,5 +191,5 @@
 
   /*
-   * Start with one reference count. The caller of this function 
+   * Start with one reference count. The caller of this function
    * must release the interface pointer when it is done.
    */
@@ -208,5 +215,5 @@
 
       case PICTYPE_METAFILE:
-	TRACE("metafile handle %08x\n", pictDesc->u.wmf.hmeta);
+	TRACE("metafile handle %p\n", pictDesc->u.wmf.hmeta);
 	newObject->himetricWidth = pictDesc->u.wmf.xExt;
 	newObject->himetricHeight = pictDesc->u.wmf.yExt;
@@ -223,5 +230,5 @@
       newObject->desc.picType = PICTYPE_UNINITIALIZED;
   }
-    
+
   TRACE("returning %p\n", newObject);
   return newObject;
@@ -235,5 +242,5 @@
  * this object.  */
 static void OLEPictureImpl_Destroy(OLEPictureImpl* Obj)
-{ 
+{
   TRACE("(%p)\n", Obj);
 
@@ -257,4 +264,5 @@
     }
   }
+  if (Obj->data) HeapFree(GetProcessHeap(), 0, Obj->data);
   HeapFree(GetProcessHeap(), 0, Obj);
 }
@@ -280,34 +288,34 @@
   if ( (This==0) || (ppvObject==0) )
     return E_INVALIDARG;
-  
+
   /*
    * Initialize the return parameter.
    */
   *ppvObject = 0;
-  
+
   /*
    * Compare the riid with the interface IDs implemented by this object.
    */
-  if (memcmp(&IID_IUnknown, riid, sizeof(IID_IUnknown)) == 0) 
+  if (memcmp(&IID_IUnknown, riid, sizeof(IID_IUnknown)) == 0)
   {
     *ppvObject = (IPicture*)This;
   }
-  else if (memcmp(&IID_IPicture, riid, sizeof(IID_IPicture)) == 0) 
+  else if (memcmp(&IID_IPicture, riid, sizeof(IID_IPicture)) == 0)
   {
     *ppvObject = (IPicture*)This;
   }
-  else if (memcmp(&IID_IDispatch, riid, sizeof(IID_IDispatch)) == 0) 
+  else if (memcmp(&IID_IDispatch, riid, sizeof(IID_IDispatch)) == 0)
   {
     *ppvObject = (IDispatch*)&(This->lpvtbl2);
   }
-  else if (memcmp(&IID_IPictureDisp, riid, sizeof(IID_IPictureDisp)) == 0) 
+  else if (memcmp(&IID_IPictureDisp, riid, sizeof(IID_IPictureDisp)) == 0)
   {
     *ppvObject = (IDispatch*)&(This->lpvtbl2);
   }
-  else if (memcmp(&IID_IPersistStream, riid, sizeof(IID_IPersistStream)) == 0) 
+  else if (memcmp(&IID_IPersistStream, riid, sizeof(IID_IPersistStream)) == 0)
   {
   *ppvObject = (IPersistStream*)&(This->lpvtbl3);
   }
-  else if (memcmp(&IID_IConnectionPointContainer, riid, sizeof(IID_IConnectionPointContainer)) == 0) 
+  else if (memcmp(&IID_IConnectionPointContainer, riid, sizeof(IID_IConnectionPointContainer)) == 0)
   {
   *ppvObject = (IConnectionPointContainer*)&(This->lpvtbl4);
@@ -321,5 +329,5 @@
     return E_NOINTERFACE;
   }
-  
+
   /*
    * Query Interface always increases the reference count by one when it is
@@ -328,5 +336,5 @@
   OLEPictureImpl_AddRef((IPicture*)This);
 
-  return S_OK;;
+  return S_OK;
 }
 /***********************************************************************
@@ -360,5 +368,5 @@
  * See Windows documentation for more details on IUnknown methods.
  */
-static ULONG WINAPI OLEPictureImpl_AddRef( 
+static ULONG WINAPI OLEPictureImpl_AddRef(
   IPicture* iface)
 {
@@ -369,5 +377,5 @@
   return This->ref;
 }
-        
+
 /************************************************************************
  * OLEPictureImpl_Release (IUnknown)
@@ -375,5 +383,5 @@
  * See Windows documentation for more details on IUnknown methods.
  */
-static ULONG WINAPI OLEPictureImpl_Release( 
+static ULONG WINAPI OLEPictureImpl_Release(
       IPicture* iface)
 {
@@ -395,5 +403,5 @@
     return 0;
   }
-  
+
   return This->ref;
 }
@@ -402,5 +410,5 @@
 /************************************************************************
  * OLEPictureImpl_get_Handle
- */ 
+ */
 static HRESULT WINAPI OLEPictureImpl_get_Handle(IPicture *iface,
 						OLE_HANDLE *phandle)
@@ -410,14 +418,14 @@
   switch(This->desc.picType) {
   case PICTYPE_BITMAP:
-    *phandle = This->desc.u.bmp.hbitmap;
+    *phandle = (OLE_HANDLE)This->desc.u.bmp.hbitmap;
     break;
   case PICTYPE_METAFILE:
-    *phandle = This->desc.u.wmf.hmeta;
+    *phandle = (OLE_HANDLE)This->desc.u.wmf.hmeta;
     break;
   case PICTYPE_ICON:
-    *phandle = This->desc.u.icon.hicon;
+    *phandle = (OLE_HANDLE)This->desc.u.icon.hicon;
     break;
   case PICTYPE_ENHMETAFILE:
-    *phandle = This->desc.u.emf.hemf;
+    *phandle = (OLE_HANDLE)This->desc.u.emf.hemf;
     break;
   default:
@@ -431,5 +439,5 @@
 /************************************************************************
  * OLEPictureImpl_get_hPal
- */ 
+ */
 static HRESULT WINAPI OLEPictureImpl_get_hPal(IPicture *iface,
 					      OLE_HANDLE *phandle)
@@ -442,5 +450,5 @@
 /************************************************************************
  * OLEPictureImpl_get_Type
- */ 
+ */
 static HRESULT WINAPI OLEPictureImpl_get_Type(IPicture *iface,
 					      short *ptype)
@@ -454,5 +462,5 @@
 /************************************************************************
  * OLEPictureImpl_get_Width
- */ 
+ */
 static HRESULT WINAPI OLEPictureImpl_get_Width(IPicture *iface,
 					       OLE_XSIZE_HIMETRIC *pwidth)
@@ -466,5 +474,5 @@
 /************************************************************************
  * OLEPictureImpl_get_Height
- */ 
+ */
 static HRESULT WINAPI OLEPictureImpl_get_Height(IPicture *iface,
 						OLE_YSIZE_HIMETRIC *pheight)
@@ -478,5 +486,5 @@
 /************************************************************************
  * OLEPictureImpl_Render
- */ 
+ */
 static HRESULT WINAPI OLEPictureImpl_Render(IPicture *iface, HDC hdc,
 					    long x, long y, long cx, long cy,
@@ -488,5 +496,5 @@
 {
   ICOM_THIS(OLEPictureImpl, iface);
-  TRACE("(%p)->(%08x, (%ld,%ld), (%ld,%ld) <- (%ld,%ld), (%ld,%ld), %p)\n",
+  TRACE("(%p)->(%p, (%ld,%ld), (%ld,%ld) <- (%ld,%ld), (%ld,%ld), %p)\n",
 	This, hdc, x, y, cx, cy, xSrc, ySrc, cxSrc, cySrc, prcWBounds);
   if(prcWBounds)
@@ -540,5 +548,5 @@
 /************************************************************************
  * OLEPictureImpl_set_hPal
- */ 
+ */
 static HRESULT WINAPI OLEPictureImpl_set_hPal(IPicture *iface,
 					      OLE_HANDLE hpal)
@@ -552,10 +560,10 @@
 /************************************************************************
  * OLEPictureImpl_get_CurDC
- */ 
+ */
 static HRESULT WINAPI OLEPictureImpl_get_CurDC(IPicture *iface,
 					       HDC *phdc)
 {
   ICOM_THIS(OLEPictureImpl, iface);
-  TRACE("(%p), returning %x\n", This, This->hDCCur);
+  TRACE("(%p), returning %p\n", This, This->hDCCur);
   if (phdc) *phdc = This->hDCCur;
   return S_OK;
@@ -564,5 +572,5 @@
 /************************************************************************
  * OLEPictureImpl_SelectPicture
- */ 
+ */
 static HRESULT WINAPI OLEPictureImpl_SelectPicture(IPicture *iface,
 						   HDC hdcIn,
@@ -571,5 +579,5 @@
 {
   ICOM_THIS(OLEPictureImpl, iface);
-  TRACE("(%p)->(%08x, %p, %p)\n", This, hdcIn, phdcOut, phbmpOut);
+  TRACE("(%p)->(%p, %p, %p)\n", This, hdcIn, phdcOut, phbmpOut);
   if (This->desc.picType == PICTYPE_BITMAP) {
       SelectObject(hdcIn,This->desc.u.bmp.hbitmap);
@@ -579,5 +587,5 @@
       This->hDCCur = hdcIn;
       if (phbmpOut)
-	  *phbmpOut = This->desc.u.bmp.hbitmap;
+	  *phbmpOut = (OLE_HANDLE)This->desc.u.bmp.hbitmap;
       return S_OK;
   } else {
@@ -589,5 +597,5 @@
 /************************************************************************
  * OLEPictureImpl_get_KeepOriginalFormat
- */ 
+ */
 static HRESULT WINAPI OLEPictureImpl_get_KeepOriginalFormat(IPicture *iface,
 							    BOOL *pfKeep)
@@ -603,5 +611,5 @@
 /************************************************************************
  * OLEPictureImpl_put_KeepOriginalFormat
- */ 
+ */
 static HRESULT WINAPI OLEPictureImpl_put_KeepOriginalFormat(IPicture *iface,
 							    BOOL keep)
@@ -616,5 +624,5 @@
 /************************************************************************
  * OLEPictureImpl_PictureChanged
- */ 
+ */
 static HRESULT WINAPI OLEPictureImpl_PictureChanged(IPicture *iface)
 {
@@ -627,5 +635,5 @@
 /************************************************************************
  * OLEPictureImpl_SaveAsFile
- */ 
+ */
 static HRESULT WINAPI OLEPictureImpl_SaveAsFile(IPicture *iface,
 						IStream *pstream,
@@ -634,11 +642,11 @@
 {
   ICOM_THIS(OLEPictureImpl, iface);
-  FIXME("(%p)->(%p, %d, %p): stub\n", This, pstream, SaveMemCopy, pcbSize);
-  return E_NOTIMPL;
+  FIXME("(%p)->(%p, %d, %p), hacked stub.\n", This, pstream, SaveMemCopy, pcbSize);
+  return IStream_Write(pstream,This->data,This->datalen,(ULONG*)pcbSize);
 }
 
 /************************************************************************
  * OLEPictureImpl_get_Attributes
- */ 
+ */
 static HRESULT WINAPI OLEPictureImpl_get_Attributes(IPicture *iface,
 						    DWORD *pdwAttr)
@@ -704,5 +712,5 @@
   ICOM_THIS_From_IConnectionPointContainer(OLEPictureImpl, iface);
   TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppCP);
-  if (!ppCP) 
+  if (!ppCP)
       return E_POINTER;
   *ppCP = NULL;
@@ -824,7 +832,8 @@
   }
   xread = 0;
-  xbuf = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,header[1]);
+  xbuf = This->data = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,header[1]);
+  This->datalen = header[1];
   while (xread < header[1]) {
-    ULONG nread; 
+    ULONG nread;
     hr = IStream_Read(pStm,xbuf+xread,header[1]-xread,&nread);
     xread+=nread;
@@ -998,5 +1007,4 @@
     break;
   }
-  HeapFree(GetProcessHeap(),0,xbuf);
 
   /* FIXME: this notify is not really documented */
@@ -1072,5 +1080,5 @@
  */
 static HRESULT WINAPI OLEPictureImpl_GetTypeInfoCount(
-  IDispatch*    iface, 
+  IDispatch*    iface,
   unsigned int* pctinfo)
 {
@@ -1086,7 +1094,7 @@
  */
 static HRESULT WINAPI OLEPictureImpl_GetTypeInfo(
-  IDispatch*  iface, 
+  IDispatch*  iface,
   UINT      iTInfo,
-  LCID        lcid, 
+  LCID        lcid,
   ITypeInfo** ppTInfo)
 {
@@ -1103,7 +1111,7 @@
 static HRESULT WINAPI OLEPictureImpl_GetIDsOfNames(
   IDispatch*  iface,
-  REFIID      riid, 
-  LPOLESTR* rgszNames, 
-  UINT      cNames, 
+  REFIID      riid,
+  LPOLESTR* rgszNames,
+  UINT      cNames,
   LCID        lcid,
   DISPID*     rgDispId)
@@ -1121,10 +1129,10 @@
 static HRESULT WINAPI OLEPictureImpl_Invoke(
   IDispatch*  iface,
-  DISPID      dispIdMember, 
-  REFIID      riid, 
-  LCID        lcid, 
+  DISPID      dispIdMember,
+  REFIID      riid,
+  LCID        lcid,
   WORD        wFlags,
   DISPPARAMS* pDispParams,
-  VARIANT*    pVarResult, 
+  VARIANT*    pVarResult,
   EXCEPINFO*  pExepInfo,
   UINT*     puArgErr)
@@ -1271,12 +1279,32 @@
 
 /***********************************************************************
- * OleLoadPictureEx (OLEAUT32.425)
+ * OleLoadPictureEx (OLEAUT32.401)
  */
 HRESULT WINAPI OleLoadPictureEx( LPSTREAM lpstream, LONG lSize, BOOL fRunmode,
-		            REFIID reed, DWORD xsiz, DWORD ysiz, DWORD flags, LPVOID *ppvObj )
-{
-  FIXME("(%p,%ld,%d,%p,%lx,%lx,%lx,%p), not implemented\n",
-	lpstream, lSize, fRunmode, reed, xsiz, ysiz, flags, ppvObj);
-  return S_OK;
-}
- 
+		            REFIID riid, DWORD xsiz, DWORD ysiz, DWORD flags, LPVOID *ppvObj )
+{
+  LPPERSISTSTREAM ps;
+  IPicture	*newpic;
+  HRESULT hr;
+
+  FIXME("(%p,%ld,%d,%s,x=%ld,y=%ld,f=%lx,%p), partially implemented.\n",
+	lpstream, lSize, fRunmode, debugstr_guid(riid), xsiz, ysiz, flags, ppvObj);
+
+  hr = OleCreatePictureIndirect(NULL,riid,!fRunmode,(LPVOID*)&newpic);
+  if (hr)
+    return hr;
+  hr = IPicture_QueryInterface(newpic,&IID_IPersistStream, (LPVOID*)&ps);
+  if (hr) {
+      FIXME("Could not get IPersistStream iface from Ole Picture?\n");
+      IPicture_Release(newpic);
+      *ppvObj = NULL;
+      return hr;
+  }
+  IPersistStream_Load(ps,lpstream);
+  IPersistStream_Release(ps);
+  hr = IPicture_QueryInterface(newpic,riid,ppvObj);
+  if (hr)
+      FIXME("Failed to get interface %s from IPicture.\n",debugstr_guid(riid));
+  IPicture_Release(newpic);
+  return hr;
+}
Index: trunk/src/oleaut32/parsedt.c
===================================================================
--- trunk/src/oleaut32/parsedt.c	(revision 9394)
+++ trunk/src/oleaut32/parsedt.c	(revision 9400)
@@ -66,8 +66,8 @@
 "Thursday", "Friday", "Saturday", NULL};
 
-/* those three vars are useless, and not even initialized, so 
+/* those three vars are useless, and not even initialized, so
  * I'd rather remove them all (EPP)
  */
-int	DateStyle; 
+int	DateStyle;
 bool	EuroDates;
 int	CTimeZone;
@@ -80,4 +80,5 @@
 #define UTIME_MAXDAY (18)
 
+/* Assumes month in 1..12. Note tm_mon is 0..11 */
 #define IS_VALID_UTIME(y,m,d) (((y > UTIME_MINYEAR) \
  || ((y == UTIME_MINYEAR) && ((m > UTIME_MINMONTH) \
@@ -601,5 +602,6 @@
 						printf("DecodeDateTime- month field %s value is %d\n", field[i], val);
 #endif
-						tm->tm_mon = val;
+                        /* tm_mon is 0->11, so need to subtract one from value in table */
+						tm->tm_mon = val-1;
 						break;
 
@@ -681,7 +683,16 @@
 		tm->tm_hour += 12;
 
+    /* If parsing a time string into a date, all date parts are unset.
+       Win2k defaults these to 30 dec, 1899 so:                        */
+    if (tm->tm_year == 0 && tm->tm_mon == 0 && tm->tm_mday == 0 && fmask == DTK_TIME_M) {
+        tm->tm_year  = 1899;
+        tm->tm_mon   = 11; /* December, as tm_mon is 0..11 */
+        tm->tm_mday  = 30;
+    }
+
+
 #ifdef DATEDEBUG
 	printf("DecodeDateTime- mask %08x (%08x)", fmask, DTK_DATE_M);
-	printf(" set y%04d m%02d d%02d", tm->tm_year, tm->tm_mon, tm->tm_mday);
+	printf(" set y%04d m%02d d%02d", tm->tm_year, (tm->tm_mon+1), tm->tm_mday);
 	printf(" %02d:%02d:%02d\n", tm->tm_hour, tm->tm_min, tm->tm_sec);
 #endif
@@ -702,5 +713,5 @@
 			return -1;
 
-		if (IS_VALID_UTIME(tm->tm_year, tm->tm_mon, tm->tm_mday))
+		if (IS_VALID_UTIME(tm->tm_year, tm->tm_mon+1, tm->tm_mday))
 		{
 			/* FIXME: The code below is not correct */
@@ -910,5 +921,6 @@
 					printf("DecodeDate- month field %s value is %d\n", field[i], val);
 #endif
-					tm->tm_mon = val;
+                    /* tm_mon is 0->11, so need to subtract one from value in table */
+					tm->tm_mon = val-1;
 					break;
 
@@ -1076,5 +1088,6 @@
 #endif
 		*tmask = DTK_M(MONTH);
-		tm->tm_mon = val;
+        /* tm_mon is 0..11 */
+		tm->tm_mon = val-1;
 
 		/* no year and EuroDates enabled? then could be day */
@@ -1098,5 +1111,6 @@
 #endif
 		*tmask = DTK_M(MONTH);
-		tm->tm_mon = val;
+        /* tm_mon is 0..11 */
+		tm->tm_mon = val-1;
 
 	}
@@ -1150,5 +1164,5 @@
 		tm->tm_mday = atoi(str + 6);
 		*(str + 6) = '\0';
-		tm->tm_mon = atoi(str + 4);
+		tm->tm_mon = atoi(str + 4) - 1;  /* tm_mon is 0..11 */
 		*(str + 4) = '\0';
 		tm->tm_year = atoi(str + 0);
@@ -1182,5 +1196,5 @@
 			tm->tm_mday = atoi(str + 4);
 			*(str + 4) = '\0';
-			tm->tm_mon = atoi(str + 2);
+			tm->tm_mon = atoi(str + 2) - 1; /* tm_mon is 0..11 */
 			*(str + 2) = '\0';
 			tm->tm_year = atoi(str + 0);
@@ -1331,5 +1345,2 @@
 	return NULL;
 }
-
-
-
Index: trunk/src/oleaut32/safearray.c
===================================================================
--- trunk/src/oleaut32/safearray.c	(revision 9394)
+++ trunk/src/oleaut32/safearray.c	(revision 9400)
@@ -25,5 +25,4 @@
 #define WINE_LARGE_INTEGER
 #include "oleaut32.h"
-
 #endif
 
@@ -42,29 +41,29 @@
 
 /* Locally used methods */
-static INT  
+static INT
 endOfDim(LONG *coor, SAFEARRAYBOUND *mat, LONG dim, LONG realDim);
 
-static ULONG   
+static ULONG
 calcDisplacement(LONG *coor, SAFEARRAYBOUND *mat, LONG dim);
 
-static BOOL  
+static BOOL
 isPointer(USHORT feature);
 
-static INT   
+static INT
 getFeatures(VARTYPE vt);
 
-static BOOL  
+static BOOL
 validCoordinate(LONG *coor, SAFEARRAY *psa);
 
-static BOOL  
+static BOOL
 resizeSafeArray(SAFEARRAY *psa, LONG lDelta);
 
-static BOOL  
+static BOOL
 validArg(SAFEARRAY *psa);
 
-static ULONG   
+static ULONG
 getArraySize(SAFEARRAY *psa);
 
-static HRESULT 
+static HRESULT
 duplicateData(SAFEARRAY *psa, SAFEARRAY **ppsaOut);
 
@@ -129,7 +128,7 @@
  * Allocate the appropriate amount of memory for the SafeArray descriptor
  */
-HRESULT WINAPI SafeArrayAllocDescriptor( 
-  UINT    cDims, 
-  SAFEARRAY **ppsaOut) 
+HRESULT WINAPI SafeArrayAllocDescriptor(
+  UINT    cDims,
+  SAFEARRAY **ppsaOut)
 {
   SAFEARRAYBOUND *sab;
@@ -141,5 +140,5 @@
 
   /* Allocate memory for SAFEARRAY struc */
-  if(( (*ppsaOut)=HeapAlloc( 
+  if(( (*ppsaOut)=HeapAlloc(
         GetProcessHeap(), HEAP_ZERO_MEMORY, allocSize)) == NULL){
     return(E_UNEXPECTED);
@@ -151,5 +150,5 @@
 
 /*************************************************************************
- *		SafeArrayAllocDescriptorEx (OLEAUT32.429)
+ *		SafeArrayAllocDescriptorEx (OLEAUT32.41)
  * Allocate the appropriate amount of memory for the SafeArray descriptor
  *
@@ -158,8 +157,8 @@
  * The MSDN documentation on this doesn't tell us much.
  */
-HRESULT WINAPI SafeArrayAllocDescriptorEx( 
+HRESULT WINAPI SafeArrayAllocDescriptorEx(
   VARTYPE vt,
-  UINT    cDims, 
-  SAFEARRAY **ppsaOut) 
+  UINT    cDims,
+  SAFEARRAY **ppsaOut)
 {
   if ( (vt >= LAST_VARTYPE) ||
@@ -175,9 +174,9 @@
  */
 HRESULT WINAPI SafeArrayAllocData(
-  SAFEARRAY *psa) 
+  SAFEARRAY *psa)
 {
   ULONG  ulWholeArraySize;   /* to store the size of the whole thing */
 
-  if(! validArg(psa)) 
+  if(! validArg(psa))
     return E_INVALIDARG;
 
@@ -185,9 +184,9 @@
 
   /* Allocate memory for the data itself */
-  if((psa->pvData = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, 
+  if((psa->pvData = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
         psa->cbElements*ulWholeArraySize)) == NULL)
     return(E_UNEXPECTED);
 
-  TRACE("SafeArray: %lu bytes allocated for data at %p (%lu objects).\n", 
+  TRACE("SafeArray: %lu bytes allocated for data at %p (%lu objects).\n",
     psa->cbElements*ulWholeArraySize, psa->pvData, ulWholeArraySize);
 
@@ -197,9 +196,9 @@
 /*************************************************************************
  *		SafeArrayCreate (OLEAUT32.15)
- * Create a SafeArray object by encapsulating AllocDescriptor and AllocData 
+ * Create a SafeArray object by encapsulating AllocDescriptor and AllocData
  */
 SAFEARRAY* WINAPI SafeArrayCreate(
-  VARTYPE        vt, 
-  UINT         cDims, 
+  VARTYPE        vt,
+  UINT         cDims,
   SAFEARRAYBOUND *rgsabound)
 {
@@ -217,5 +216,5 @@
     return NULL;
 
-  /* setup data members... */ 
+  /* setup data members... */
   psa->cDims     = cDims;
   psa->fFeatures = getFeatures(vt);
@@ -230,12 +229,12 @@
   }
 
-  /* allocate memory for the data... */ 
+  /* allocate memory for the data... */
   if( FAILED( hRes = SafeArrayAllocData(psa))) {
-    SafeArrayDestroyDescriptor(psa); 
+    SafeArrayDestroyDescriptor(psa);
     ERR("() : Failed to allocate the Safe Array data\n");
     return NULL;
   }
 
-  return(psa); 
+  return(psa);
 }
 
@@ -248,11 +247,11 @@
 {
   /* Check for lockness before to free... */
-  if(psa->cLocks > 0) 
+  if(psa->cLocks > 0)
     return DISP_E_ARRAYISLOCKED;
 
   /* The array is unlocked, then, deallocate memory */
-  if(HeapFree( GetProcessHeap(), 0, psa) == FALSE) 
+  if(HeapFree( GetProcessHeap(), 0, psa) == FALSE)
     return E_UNEXPECTED;
-  
+
   return(S_OK);
 }
@@ -264,11 +263,11 @@
  *
  * Doc says (MSDN Library ) that psa->pvData should be made available (!= NULL)
- * only when psa->cLocks is > 0... I don't get it since pvData is allocated 
- * before the array is locked, therefore  
+ * only when psa->cLocks is > 0... I don't get it since pvData is allocated
+ * before the array is locked, therefore
  */
 HRESULT WINAPI SafeArrayLock(
   SAFEARRAY *psa)
 {
-  if(! validArg(psa))     
+  if(! validArg(psa))
     return E_INVALIDARG;
 
@@ -285,8 +284,8 @@
   SAFEARRAY *psa)
 {
-  if(! validArg(psa)) 
-    return E_INVALIDARG;
-
-  if (psa->cLocks > 0) 
+  if(! validArg(psa))
+    return E_INVALIDARG;
+
+  if (psa->cLocks > 0)
     psa->cLocks--;
 
@@ -300,14 +299,14 @@
  */
 HRESULT WINAPI SafeArrayPutElement(
-  SAFEARRAY *psa, 
-  LONG      *rgIndices, 
+  SAFEARRAY *psa,
+  LONG      *rgIndices,
   void      *pv)
 {
-  ULONG stepCountInSAData     = 0;    /* Number of array item to skip to get to 
+  ULONG stepCountInSAData     = 0;    /* Number of array item to skip to get to
                                          the desired one... */
   PVOID elementStorageAddress = NULL; /* Adress to store the data */
 
   /* Validate the index given */
-  if(! validCoordinate(rgIndices, psa)) 
+  if(! validCoordinate(rgIndices, psa))
     return DISP_E_BADINDEX;
   if(! validArg(psa))
@@ -318,14 +317,14 @@
     /* Figure out the number of items to skip */
     stepCountInSAData = calcDisplacement(rgIndices, psa->rgsabound, psa->cDims);
-  
+
     /* Figure out the number of byte to skip ... */
     elementStorageAddress = (char *) psa->pvData+(stepCountInSAData*psa->cbElements);
-  
+
     if(isPointer(psa->fFeatures)) { /* increment ref count for this pointer */
 
-      *((PVOID*)elementStorageAddress) = *(PVOID*)pv; 
+      *((PVOID*)elementStorageAddress) = *(PVOID*)pv;
       IUnknown_AddRef( *(IUnknown**)pv);
 
-    } else { 
+    } else {
 
       if(psa->fFeatures == FADF_BSTR) { /* Create a new object */
@@ -333,7 +332,7 @@
         if(pv &&
            ((pbstrReAllocStr = SYSDUPSTRING( (OLECHAR*)pv )) == NULL)) {
-          SafeArrayUnlock(psa);  
+          SafeArrayUnlock(psa);
           return E_OUTOFMEMORY;
-        } else 
+        } else
           *((BSTR*)elementStorageAddress) = pbstrReAllocStr;
       }
@@ -355,5 +354,5 @@
 
   TRACE("SafeArray: item put at adress %p.\n",elementStorageAddress);
-  return SafeArrayUnlock(psa);  
+  return SafeArrayUnlock(psa);
 }
 
@@ -364,15 +363,15 @@
  */
 HRESULT WINAPI SafeArrayGetElement(
-  SAFEARRAY *psa, 
-  LONG      *rgIndices, 
+  SAFEARRAY *psa,
+  LONG      *rgIndices,
   void      *pv)
 {
-  ULONG stepCountInSAData     = 0;    /* Number of array item to skip to get to 
+  ULONG stepCountInSAData     = 0;    /* Number of array item to skip to get to
                                          the desired one... */
   PVOID elementStorageAddress = NULL; /* Adress to store the data */
 
-  if(! validArg(psa)) 
-    return E_INVALIDARG;
-  
+  if(! validArg(psa))
+    return E_INVALIDARG;
+
   if(! validCoordinate(rgIndices, psa)) /* Validate the index given */
     return(DISP_E_BADINDEX);
@@ -382,8 +381,8 @@
     /* Figure out the number of items to skip */
     stepCountInSAData = calcDisplacement(rgIndices, psa->rgsabound, psa->cDims);
-  
+
     /* Figure out the number of byte to skip ... */
     elementStorageAddress = (char *) psa->pvData+(stepCountInSAData*psa->cbElements);
-  
+
     if( psa->fFeatures == FADF_BSTR) {           /* reallocate the obj */
       BSTR pbstrStoredStr = *(OLECHAR**)elementStorageAddress;
@@ -393,6 +392,6 @@
         SafeArrayUnlock(psa);
         return E_OUTOFMEMORY;
-      } else 
-        *((BSTR*)pv) = pbstrReturnedStr; 
+      } else
+        *((BSTR*)pv) = pbstrReturnedStr;
     }
     else if( psa->fFeatures == FADF_VARIANT) {
@@ -406,5 +405,5 @@
     }
     else if( isPointer(psa->fFeatures) )         /* simply copy the pointer */
-      *(PVOID*)pv = *((PVOID*)elementStorageAddress); 
+      *(PVOID*)pv = *((PVOID*)elementStorageAddress);
     else                                         /* copy the bytes */
       memcpy(pv, elementStorageAddress, psa->cbElements );
@@ -415,5 +414,5 @@
   }
 
-  return( SafeArrayUnlock(psa) );  
+  return( SafeArrayUnlock(psa) );
 }
 
@@ -423,12 +422,12 @@
  */
 HRESULT WINAPI SafeArrayGetUBound(
-  SAFEARRAY *psa, 
+  SAFEARRAY *psa,
   UINT    nDim,
   LONG      *plUbound)
 {
-  if(! validArg(psa))   
-    return E_INVALIDARG;
-
-  if(nDim > psa->cDims) 
+  if(! validArg(psa))
+    return E_INVALIDARG;
+
+  if(nDim > psa->cDims)
     return DISP_E_BADINDEX;
 
@@ -436,5 +435,5 @@
     return DISP_E_BADINDEX;
 
-  *plUbound = psa->rgsabound[nDim-1].lLbound + 
+  *plUbound = psa->rgsabound[nDim-1].lLbound +
               psa->rgsabound[nDim-1].cElements - 1;
 
@@ -444,20 +443,20 @@
 /*************************************************************************
  *		SafeArrayGetLBound (OLEAUT32.20)
- * Return the LO bound for a given array dimension 
+ * Return the LO bound for a given array dimension
  */
 HRESULT WINAPI SafeArrayGetLBound(
   SAFEARRAY *psa,
-  UINT    nDim, 
+  UINT    nDim,
   LONG      *plLbound)
 {
-  if(! validArg(psa))   
-    return E_INVALIDARG;
-
-  if(nDim > psa->cDims) 
+  if(! validArg(psa))
+    return E_INVALIDARG;
+
+  if(nDim > psa->cDims)
     return DISP_E_BADINDEX;
 
   if(0 == nDim)
     return DISP_E_BADINDEX;
-  
+
   *plLbound = psa->rgsabound[nDim-1].lLbound;
   return S_OK;
@@ -470,10 +469,10 @@
 UINT WINAPI SafeArrayGetDim(
   SAFEARRAY * psa)
-{ 
+{
   /*
    * A quick test in Windows shows that the behavior here for an invalid
    * pointer is to return 0.
    */
-  if(! validArg(psa)) 
+  if(! validArg(psa))
     return 0;
 
@@ -487,10 +486,10 @@
 UINT WINAPI SafeArrayGetElemsize(
   SAFEARRAY * psa)
-{ 
+{
   /*
    * A quick test in Windows shows that the behavior here for an invalid
    * pointer is to return 0.
    */
-  if(! validArg(psa)) 
+  if(! validArg(psa))
     return 0;
 
@@ -500,13 +499,13 @@
 /*************************************************************************
  *		SafeArrayAccessData (OLEAUT32.23)
- * increment the access count and return the data 
+ * increment the access count and return the data
  */
 HRESULT WINAPI SafeArrayAccessData(
-  SAFEARRAY *psa, 
+  SAFEARRAY *psa,
   void      **ppvData)
-{ 
+{
   HRESULT hRes;
 
-  if(! validArg(psa)) 
+  if(! validArg(psa))
     return E_INVALIDARG;
 
@@ -514,5 +513,5 @@
 
   switch (hRes) {
-    case S_OK: 
+    case S_OK:
       (*ppvData) = psa->pvData;
       break;
@@ -521,5 +520,5 @@
       return E_INVALIDARG;
   }
-  
+
   return S_OK;
 }
@@ -532,6 +531,6 @@
 HRESULT WINAPI SafeArrayUnaccessData(
   SAFEARRAY * psa)
-{ 
-  if(! validArg(psa)) 
+{
+  if(! validArg(psa))
     return E_INVALIDARG;
 
@@ -539,20 +538,20 @@
 }
 
-/************************************************************************ 
+/************************************************************************
  *		SafeArrayPtrOfIndex (OLEAUT32.148)
  * Return a pointer to the element at rgIndices
  */
 HRESULT WINAPI SafeArrayPtrOfIndex(
-  SAFEARRAY *psa, 
-  LONG      *rgIndices, 
+  SAFEARRAY *psa,
+  LONG      *rgIndices,
   void      **ppvData)
-{ 
-  ULONG stepCountInSAData     = 0;    /* Number of array item to skip to get to 
+{
+  ULONG stepCountInSAData     = 0;    /* Number of array item to skip to get to
                                          the desired one... */
 
-  if(! validArg(psa))                   
-    return E_INVALIDARG;
-
-  if(! validCoordinate(rgIndices, psa)) 
+  if(! validArg(psa))
+    return E_INVALIDARG;
+
+  if(! validCoordinate(rgIndices, psa))
     return DISP_E_BADINDEX;
 
@@ -563,5 +562,5 @@
   /* Figure out the number of items to skip */
   stepCountInSAData = calcDisplacement(rgIndices, psa->rgsabound, psa->cDims);
-  
+
   *ppvData = (char *) psa->pvData+(stepCountInSAData*psa->cbElements);
 
@@ -569,5 +568,5 @@
 }
 
-/************************************************************************ 
+/************************************************************************
  *		SafeArrayDestroyData (OLEAUT32.39)
  * Frees the memory data bloc
@@ -575,13 +574,13 @@
 HRESULT WINAPI SafeArrayDestroyData(
   SAFEARRAY *psa)
-{ 
+{
   HRESULT  hRes;
   ULONG    ulWholeArraySize; /* count spot in array  */
   ULONG    ulDataIter;       /* to iterate the data space */
 
-  if(! validArg(psa)) 
-    return E_INVALIDARG;
-
-  if(psa->cLocks > 0) 
+  if(! validArg(psa))
+    return E_INVALIDARG;
+
+  if(psa->cLocks > 0)
     return DISP_E_ARRAYISLOCKED;
 
@@ -592,7 +591,7 @@
 
     for(ulDataIter=0; ulDataIter < ulWholeArraySize; ulDataIter++) {
-      punk = *(IUnknown**)((char *) psa->pvData+(ulDataIter*(psa->cbElements)));	
-
-      if( punk != NULL) 
+      punk = *(IUnknown**)((char *) psa->pvData+(ulDataIter*(psa->cbElements)));
+
+      if( punk != NULL)
         IUnknown_Release(punk);
     }
@@ -605,5 +604,5 @@
       bstr = *(BSTR*)((char *) psa->pvData+(ulDataIter*(psa->cbElements)));
 
-      if( bstr != NULL) 
+      if( bstr != NULL)
         SysFreeString( bstr );
     }
@@ -615,6 +614,6 @@
     }
   }
-      
-  /* check if this array is a Vector, in which case do not free the data 
+
+  /* check if this array is a Vector, in which case do not free the data
      block since it has been allocated by AllocDescriptor and therefore
      deserve to be freed by DestroyDescriptor */
@@ -627,9 +626,9 @@
     psa->pvData = NULL;
   }
-  
+
   return S_OK;
 }
 
-/************************************************************************ 
+/************************************************************************
  *		SafeArrayCopyData (OLEAUT32.412)
  * Copy the psaSource's data block into psaTarget if dimension and size
@@ -639,12 +638,12 @@
   SAFEARRAY *psaSource,
   SAFEARRAY **psaTarget)
-{ 
+{
   USHORT   cDimCount;        /* looper */
   LONG     lDelta;           /* looper */
-  IUnknown *punk;   
+  IUnknown *punk;
   ULONG    ulWholeArraySize; /* Number of item in SA */
   BSTR   bstr;
 
-  if(! (validArg(psaSource) && validArg(*psaTarget)) ) 
+  if(! (validArg(psaSource) && validArg(*psaTarget)) )
     return E_INVALIDARG;
 
@@ -652,13 +651,13 @@
     return E_INVALIDARG;
 
-  ulWholeArraySize = getArraySize(psaSource); 
+  ulWholeArraySize = getArraySize(psaSource);
 
   /* The two arrays boundaries must be of same lenght */
   for(cDimCount=0;cDimCount < psaSource->cDims; cDimCount++)
-    if( psaSource->rgsabound[cDimCount].cElements != 
+    if( psaSource->rgsabound[cDimCount].cElements !=
       (*psaTarget)->rgsabound[cDimCount].cElements)
       return E_INVALIDARG;
 
-  if( isPointer((*psaTarget)->fFeatures) ) {         /* the target contains ptr 
+  if( isPointer((*psaTarget)->fFeatures) ) {         /* the target contains ptr
                                                         that must be released */
     for(lDelta=0;lDelta < ulWholeArraySize; lDelta++) {
@@ -666,5 +665,5 @@
         ((char *) (*psaTarget)->pvData + (lDelta * (*psaTarget)->cbElements));
 
-      if( punk != NULL) 
+      if( punk != NULL)
         IUnknown_Release(punk);
     }
@@ -672,10 +671,10 @@
   }
   else if( (*psaTarget)->fFeatures & FADF_BSTR) {    /* the target contain BSTR
-                                                        that must be freed */ 
+                                                        that must be freed */
     for(lDelta=0;lDelta < ulWholeArraySize; lDelta++) {
-      bstr = 
+      bstr =
         *(BSTR*)((char *) (*psaTarget)->pvData + (lDelta * (*psaTarget)->cbElements));
 
-      if( bstr != NULL) 
+      if( bstr != NULL)
         SysFreeString( bstr );
     }
@@ -691,5 +690,5 @@
 }
 
-/************************************************************************ 
+/************************************************************************
  *		SafeArrayDestroy (OLEAUT32.16)
  * Deallocates all memory reserved for the SafeArray
@@ -697,11 +696,11 @@
 HRESULT WINAPI SafeArrayDestroy(
   SAFEARRAY * psa)
-{ 
+{
   HRESULT hRes;
 
-  if(! validArg(psa)) 
-    return E_INVALIDARG;
-
-  if(psa->cLocks > 0) 
+  if(! validArg(psa))
+    return E_INVALIDARG;
+
+  if(psa->cLocks > 0)
     return DISP_E_ARRAYISLOCKED;
 
@@ -713,17 +712,17 @@
 }
 
-/************************************************************************ 
+/************************************************************************
  *		SafeArrayCopy (OLEAUT32.27)
  * Make a dupplicate of a SafeArray
  */
 HRESULT WINAPI SafeArrayCopy(
-  SAFEARRAY *psa, 
+  SAFEARRAY *psa,
   SAFEARRAY **ppsaOut)
-{ 
+{
   HRESULT hRes;
   DWORD   dAllocSize;
   ULONG   ulWholeArraySize; /* size of the thing */
 
-  if(! validArg(psa)) 
+  if(! validArg(psa))
     return E_INVALIDARG;
 
@@ -731,5 +730,5 @@
 
     /* Duplicate the SAFEARRAY struc */
-    memcpy(*ppsaOut, psa, 
+    memcpy(*ppsaOut, psa,
             sizeof(*psa)+(sizeof(*(psa->rgsabound))*(psa->cDims-1)));
 
@@ -738,11 +737,11 @@
     /* make sure the new safe array doesn't have the FADF_CREATEVECTOR flag,
        because the data has not been allocated with the descriptor. */
-    (*ppsaOut)->fFeatures &= ~FADF_CREATEVECTOR;  
- 
-    /* Get the allocated memory size for source and allocate it for target */ 
+    (*ppsaOut)->fFeatures &= ~FADF_CREATEVECTOR;
+
+    /* Get the allocated memory size for source and allocate it for target */
     ulWholeArraySize = getArraySize(psa); /* Number of item in SA */
     dAllocSize = ulWholeArraySize*psa->cbElements;
 
-    (*ppsaOut)->pvData = 
+    (*ppsaOut)->pvData =
       HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dAllocSize);
     if( (*ppsaOut)->pvData != NULL) {   /* HeapAlloc succeed */
@@ -754,5 +753,5 @@
         return hRes;
       }
-        
+
     } else { /* failed to allocate or dupplicate... */
       SafeArrayDestroyDescriptor(*ppsaOut);
@@ -766,14 +765,14 @@
 }
 
-/************************************************************************ 
+/************************************************************************
  *		SafeArrayCreateVector (OLEAUT32.411)
- * Creates a one dimension safearray where the data is next to the 
+ * Creates a one dimension safearray where the data is next to the
  * SAFEARRAY structure.
  */
 SAFEARRAY* WINAPI SafeArrayCreateVector(
-  VARTYPE vt, 
-  LONG    lLbound, 
-  ULONG   cElements) 
-{ 
+  VARTYPE vt,
+  LONG    lLbound,
+  ULONG   cElements)
+{
   SAFEARRAY *psa;
 
@@ -784,11 +783,11 @@
 
   /* Allocate memory for the array descriptor and data contiguously  */
-  if( FAILED( psa = HeapAlloc( GetProcessHeap(), 
-                      HEAP_ZERO_MEMORY, 
+  if( FAILED( psa = HeapAlloc( GetProcessHeap(),
+                      HEAP_ZERO_MEMORY,
                       (sizeof(*psa) + (VARTYPE_SIZE[vt] * cElements))))) {
     return NULL;
   }
-										
-  /* setup data members... */ 
+
+  /* setup data members... */
   psa->cDims      = 1; /* always and forever */
   psa->fFeatures  = getFeatures(vt) | FADF_CREATEVECTOR;  /* undocumented flag used by Microsoft */
@@ -800,28 +799,28 @@
   psa->rgsabound[0].lLbound   = lLbound;
 
-  return(psa); 				  
-} 
-
-/************************************************************************ 
+  return(psa);
+}
+
+/************************************************************************
  *		SafeArrayRedim (OLEAUT32.40)
  * Changes the caracteristics of the last dimension of the SafeArray
  */
 HRESULT WINAPI SafeArrayRedim(
-  SAFEARRAY      *psa, 
+  SAFEARRAY      *psa,
   SAFEARRAYBOUND *psaboundNew)
-{ 
+{
   LONG   lDelta;  /* hold difference in size */
   USHORT cDims=1; /* dims counter */
 
-  if( !validArg(psa) )                    
-    return E_INVALIDARG;
-
-  if( psa->cLocks > 0 )                    
+  if( !validArg(psa) )
+    return E_INVALIDARG;
+
+  if( psa->cLocks > 0 )
     return DISP_E_ARRAYISLOCKED;
 
-  if( psa->fFeatures & FADF_FIXEDSIZE )    
-    return E_INVALIDARG;
-
-  if( SafeArrayLock(psa)==E_UNEXPECTED ) 
+  if( psa->fFeatures & FADF_FIXEDSIZE )
+    return E_INVALIDARG;
+
+  if( SafeArrayLock(psa)==E_UNEXPECTED )
     return E_UNEXPECTED;/* UNDOC error condition */
 
@@ -837,8 +836,8 @@
 
   } else /* need to enlarge (lDelta +) reduce (lDelta -) */
-    if(! resizeSafeArray(psa, lDelta)) 
+    if(! resizeSafeArray(psa, lDelta))
       return E_UNEXPECTED; /* UNDOC error condition */
 
-  /* the only modifyable dimension sits in [0] as the dimensions were reversed  
+  /* the only modifyable dimension sits in [0] as the dimensions were reversed
      at array creation time... */
   psa->rgsabound[0].cElements = psaboundNew->cElements;
@@ -852,9 +851,9 @@
  ************************************************************************/
 
-/************************************************************************ 
+/************************************************************************
  * Used to validate the SAFEARRAY type of arg
  */
 static BOOL validArg(
-  SAFEARRAY *psa) 
+  SAFEARRAY *psa)
 {
   SAFEARRAYBOUND *sab;
@@ -886,13 +885,13 @@
 }
 
-/************************************************************************ 
+/************************************************************************
  * Used to reallocate memory
  */
 static BOOL resizeSafeArray(
-  SAFEARRAY *psa, 
+  SAFEARRAY *psa,
   LONG lDelta)
 {
   ULONG    ulWholeArraySize;  /* use as multiplicator */
-  PVOID    pvNewBlock = NULL;  
+  PVOID    pvNewBlock = NULL;
   IUnknown *punk;
   BSTR   bstr;
@@ -905,5 +904,5 @@
 	      punk = *(IUnknown**)
           ((char *) psa->pvData+((ulWholeArraySize+lDelta)*psa->cbElements));
-	
+
         if( punk != NULL )
           IUnknown_Release(punk);
@@ -926,11 +925,11 @@
   if (!(psa->fFeatures & FADF_CREATEVECTOR))
   {
-    /* Ok now, if we are enlarging the array, we *MUST* move the whole block 
+    /* Ok now, if we are enlarging the array, we *MUST* move the whole block
        pointed to by pvData.   If we are shorthening the array, this move is
-       optional but we do it anyway becuase the benefit is that we are 
+       optional but we do it anyway becuase the benefit is that we are
        releasing to the system the unused memory */
 
-    if((pvNewBlock = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, psa->pvData, 
-       (ulWholeArraySize + lDelta) * psa->cbElements)) == NULL) 
+    if((pvNewBlock = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, psa->pvData,
+       (ulWholeArraySize + lDelta) * psa->cbElements)) == NULL)
         return FALSE; /* TODO If we get here it means:
                          SHRINK situation :  we've deleted the undesired
@@ -941,9 +940,9 @@
   else
   {
-    /* Allocate a new block, because the previous data has been allocated with 
+    /* Allocate a new block, because the previous data has been allocated with
        the descriptor in SafeArrayCreateVector function. */
 
     if((pvNewBlock = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
-       ulWholeArraySize * psa->cbElements)) == NULL) 
+       ulWholeArraySize * psa->cbElements)) == NULL)
         return FALSE;
 
@@ -955,9 +954,9 @@
 }
 
-/************************************************************************ 
- * Used to set the fFeatures data member of the SAFEARRAY structure. 
+/************************************************************************
+ * Used to set the fFeatures data member of the SAFEARRAY structure.
  */
 static INT getFeatures(
-  VARTYPE vt) 
+  VARTYPE vt)
 {
   switch(vt) {
@@ -970,10 +969,10 @@
 }
 
-/************************************************************************ 
- * Used to figure out if the fFeatures data member of the SAFEARRAY 
- * structure contain any information about the type of data stored... 
+/************************************************************************
+ * Used to figure out if the fFeatures data member of the SAFEARRAY
+ * structure contain any information about the type of data stored...
  */
 static BOOL isPointer(
-  USHORT feature) 
+  USHORT feature)
 {
   switch(feature) {
@@ -984,6 +983,6 @@
 }
 
-/************************************************************************ 
- * Used to calculate the displacement when accessing or modifying 
+/************************************************************************
+ * Used to calculate the displacement when accessing or modifying
  * safearray data set.
  *
@@ -995,14 +994,14 @@
  */
 static ULONG calcDisplacement(
-  LONG           *coor, 
-  SAFEARRAYBOUND *mat, 
-  LONG           dim) 
+  LONG           *coor,
+  SAFEARRAYBOUND *mat,
+  LONG           dim)
 {
   ULONG res = 0;
   LONG  iterDim;
 
-  for(iterDim=0; iterDim<dim; iterDim++) 
+  for(iterDim=0; iterDim<dim; iterDim++)
     /* the -mat[dim] bring coor[dim] relative to 0 for calculation */
-    res += ((coor[iterDim]-mat[iterDim].lLbound) * 
+    res += ((coor[iterDim]-mat[iterDim].lLbound) *
             endOfDim(coor, mat, iterDim+1, dim));
 
@@ -1011,28 +1010,28 @@
 }
 
-/************************************************************************ 
- * Recursivity agent for calcDisplacement method.  Used within Put and 
+/************************************************************************
+ * Recursivity agent for calcDisplacement method.  Used within Put and
  * Get methods.
  */
 static INT endOfDim(
-  LONG           *coor, 
-  SAFEARRAYBOUND *mat, 
-  LONG           dim, 
-  LONG           realDim) 
-{
-  if(dim==realDim) 
+  LONG           *coor,
+  SAFEARRAYBOUND *mat,
+  LONG           dim,
+  LONG           realDim)
+{
+  if(dim==realDim)
     return 1;
-  else 
+  else
     return (endOfDim(coor, mat, dim+1, realDim) * mat[dim].cElements);
 }
 
 
-/************************************************************************ 
- * Method used to validate the coordinate received in Put and Get 
+/************************************************************************
+ * Method used to validate the coordinate received in Put and Get
  * methods.
  */
 static BOOL validCoordinate(
-  LONG      *coor, 
-  SAFEARRAY *psa) 
+  LONG      *coor,
+  SAFEARRAY *psa)
 {
   INT   iter=0;
@@ -1048,7 +1047,7 @@
     if((hRes = SafeArrayGetUBound(psa, (iter+1), &lUBound)) != S_OK)
       return FALSE;
- 
-    if(lLBound > lUBound) 
-      return FALSE; 
+
+    if(lLBound > lUBound)
+      return FALSE;
 
     if((coor[iter] < lLBound) || (coor[iter] > lUBound))
@@ -1056,13 +1055,13 @@
   }
   return TRUE;
-}  
-
-/************************************************************************ 
+}
+
+/************************************************************************
  * Method used to calculate the number of cells of the SA
  */
 static ULONG getArraySize(
-  SAFEARRAY *psa) 
-{
-  USHORT cCount; 
+  SAFEARRAY *psa)
+{
+  USHORT cCount;
   ULONG  ulWholeArraySize = 1;
 
@@ -1070,14 +1069,14 @@
     ulWholeArraySize *= psa->rgsabound[cCount].cElements;
 
-  return ulWholeArraySize;  
-}
-
-
-/************************************************************************ 
+  return ulWholeArraySize;
+}
+
+
+/************************************************************************
  * Method used to handle data space dupplication for Copy32 and CopyData32
  */
 static HRESULT duplicateData(
-  SAFEARRAY *psa, 
-  SAFEARRAY **ppsaOut) 
+  SAFEARRAY *psa,
+  SAFEARRAY **ppsaOut)
 {
   ULONG    ulWholeArraySize; /* size of the thing */
@@ -1085,8 +1084,8 @@
 
   ulWholeArraySize = getArraySize(psa); /* Number of item in SA */
-  
+
   SafeArrayLock(*ppsaOut);
 
-  if( isPointer(psa->fFeatures) ) {  /* If datatype is object increment 
+  if( isPointer(psa->fFeatures) ) {  /* If datatype is object increment
                                         object's reference count */
     IUnknown *punk;
@@ -1100,9 +1099,9 @@
 
     /* Copy the source array data into target array */
-    memcpy((*ppsaOut)->pvData, psa->pvData, 
+    memcpy((*ppsaOut)->pvData, psa->pvData,
       ulWholeArraySize*psa->cbElements);
 
   }
-  else if( psa->fFeatures & FADF_BSTR ) { /* if datatype is BSTR allocate 
+  else if( psa->fFeatures & FADF_BSTR ) { /* if datatype is BSTR allocate
                                              the BSTR in the new array */
     BSTR   pbstrReAllocStr = NULL;
@@ -1116,5 +1115,5 @@
       }
 
-      *((BSTR*)((char *) (*ppsaOut)->pvData+(lDelta * psa->cbElements))) = 
+      *((BSTR*)((char *) (*ppsaOut)->pvData+(lDelta * psa->cbElements))) =
         pbstrReAllocStr;
     }
@@ -1131,5 +1130,5 @@
   else { /* Simply copy the source array data into target array */
 
-    memcpy((*ppsaOut)->pvData, psa->pvData, 
+    memcpy((*ppsaOut)->pvData, psa->pvData,
       ulWholeArraySize*psa->cbElements);
   }
@@ -1141,9 +1140,9 @@
 
 
-/************************************************************************ 
- *		SafeArrayGetVarType (OLEAUT32.77)
+/************************************************************************
+ *		SafeArrayGetVartype (OLEAUT32.77)
  * Returns the VARTYPE stored in the given safearray
  */
-HRESULT WINAPI SafeArrayGetVarType(
+HRESULT WINAPI SafeArrayGetVartype(
   SAFEARRAY* psa,
   VARTYPE*   pvt)
Index: trunk/src/oleaut32/stubs.cpp
===================================================================
--- trunk/src/oleaut32/stubs.cpp	(revision 9394)
+++ trunk/src/oleaut32/stubs.cpp	(revision 9400)
@@ -1,3 +1,3 @@
-/* $Id: stubs.cpp,v 1.15 2002-05-17 10:17:00 sandervl Exp $ */
+/* $Id: stubs.cpp,v 1.16 2002-11-12 17:07:47 sandervl Exp $ */
 /* 
  * Win32 COM/OLE stubs for OS/2
@@ -96,13 +96,4 @@
 }
 
-//*****************************************************************************
-//*****************************************************************************
-HRESULT WINAPI DispCallFunc(void* pvInstance, ULONG oVft, CALLCONV cc,
-            VARTYPE vtReturn, UINT  cActuals, VARTYPE* prgvt,
-            VARIANTARG** prgpvarg, VARIANT* pvargResult)
-{
-    dprintf(("OLEAUT32: DispCallFunc - stub"));
-    return S_OK;
-}
 
 //*****************************************************************************
Index: trunk/src/oleaut32/tmarshal.c
===================================================================
--- trunk/src/oleaut32/tmarshal.c	(revision 9394)
+++ trunk/src/oleaut32/tmarshal.c	(revision 9400)
@@ -41,5 +41,5 @@
 #include "typelib.h"
 #include "wine/debug.h"
-#include "ntddk.h"
+#include "winternl.h"
 
 static const WCHAR riidW[5] = {'r','i','i','d',0};
@@ -367,5 +367,5 @@
 
 /* how much space do we use on stack in DWORD steps. */
-static int const
+int const
 _argsize(DWORD vt) {
     switch (vt) {
Index: trunk/src/oleaut32/typelib.c
===================================================================
--- trunk/src/oleaut32/typelib.c	(revision 9394)
+++ trunk/src/oleaut32/typelib.c	(revision 9400)
@@ -20,16 +20,16 @@
  * License along with this library; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *                    
+ *
  * --------------------------------------------------------------------------------------
  * Known problems (2000, Francois Jacques)
  *
  * - Tested using OLEVIEW (Platform SDK tool) only.
- *   
- * - dual interface dispinterfaces. vtable-interface ITypeInfo instances are 
- *   creating by doing a straight copy of the dispinterface instance and just changing 
+ *
+ * - dual interface dispinterfaces. vtable-interface ITypeInfo instances are
+ *   creating by doing a straight copy of the dispinterface instance and just changing
  *   its typekind. Pointed structures aren't copied - only the address of the pointers.
  *   So when you release the dispinterface, you delete the vtable-interface structures
  *   as well... fortunately, clean up of structures is not implemented.
- * 
+ *
  * - locale stuff is partially implemented but hasn't been tested.
  *
@@ -50,8 +50,9 @@
  * -. some methods just return pointers to internal data structures, this is
  *      partly laziness, partly I want to check how windows does it.
- * 
+ *
  */
 
 #include "config.h"
+#include "wine/port.h"
 
 #include <stdlib.h>
@@ -71,8 +72,73 @@
 #include "typelib.h"
 #include "wine/debug.h"
-#include "ntddk.h"
+#include "parsedt.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(ole);
 WINE_DECLARE_DEBUG_CHANNEL(typelib);
+
+/****************************************************************************
+ *              FromLExxx
+ *
+ * Takes p_iVal (which is in little endian) and returns it
+ *   in the host machine's byte order.
+ */
+#ifdef WORDS_BIGENDIAN
+static WORD FromLEWord(WORD p_iVal)
+{
+  return (((p_iVal & 0x00FF) << 8) |
+	  ((p_iVal & 0xFF00) >> 8));
+}
+
+
+static DWORD FromLEDWord(DWORD p_iVal)
+{
+  return (((p_iVal & 0x000000FF) << 24) |
+	  ((p_iVal & 0x0000FF00) <<  8) |
+	  ((p_iVal & 0x00FF0000) >>  8) |
+	  ((p_iVal & 0xFF000000) >> 24));
+}
+#else
+#define FromLEWord(X)  (X)
+#define FromLEDWord(X) (X)
+#endif
+
+
+/****************************************************************************
+ *              FromLExxx
+ *
+ * Fix byte order in any structure if necessary
+ */
+#ifdef WORDS_BIGENDIAN
+static void FromLEWords(void *p_Val, int p_iSize)
+{
+  WORD *Val = p_Val;
+
+  p_iSize /= sizeof(WORD);
+
+  while (p_iSize) {
+    *Val = FromLEWord(*Val);
+    Val++;
+    p_iSize--;
+  }
+}
+
+
+static void FromLEDWords(void *p_Val, int p_iSize)
+{
+  DWORD *Val = p_Val;
+
+  p_iSize /= sizeof(DWORD);
+
+  while (p_iSize) {
+    *Val = FromLEDWord(*Val);
+    Val++;
+    p_iSize--;
+  }
+}
+#else
+#define FromLEWords(X,Y) /*nothing*/
+#define FromLEDWords(X,Y) /*nothing*/
+#endif
+
 
 /****************************************************************************
@@ -84,5 +150,5 @@
  */
 HRESULT WINAPI
-QueryPathOfRegTypeLib16(	
+QueryPathOfRegTypeLib16(
 	REFGUID guid,	/* [in] referenced guid */
 	WORD wMaj,	/* [in] major version */
@@ -119,5 +185,5 @@
 	return S_OK;
 }
- 
+
 /****************************************************************************
  *		QueryPathOfRegTypeLib	[OLEAUT32.164]
@@ -126,5 +192,5 @@
  */
 HRESULT WINAPI
-QueryPathOfRegTypeLib(	
+QueryPathOfRegTypeLib(
 	REFGUID guid,	/* [in] referenced guid */
 	WORD wMaj,	/* [in] major version */
@@ -160,5 +226,5 @@
             "SOFTWARE\\Classes\\Typelib\\{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}\\%d.%d\\%lx\\win32",
             guid->Data1,    guid->Data2,    guid->Data3,
-            guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3], 
+            guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
             guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7],
             wMaj,
@@ -200,8 +266,8 @@
         }
     }
-	
+
     if (hr != S_OK)
 		TRACE_(typelib)("%s not found\n", szTypeLibKey);
-	
+
     return hr;
 }
@@ -281,5 +347,5 @@
     INT index = 1;
     TRACE("(%s,%d,%p)\n",debugstr_w(szFile), regkind, pptLib);
-    
+
     if(!SearchPathW(NULL,szFile,NULL,sizeof(szPath)/sizeof(WCHAR),szPath,
 		    NULL)) {
@@ -288,5 +354,5 @@
         pIndexStr = strrchrW(szFile, '\\');
 	if(pIndexStr && pIndexStr != szFile && *++pIndexStr != '\0') {
-	    index = wcstol(pIndexStr, NULL, 10);
+	    index = atoiW(pIndexStr);
 	    memcpy(szFileCopy, szFile,
 		   (pIndexStr - szFile - 1) * sizeof(WCHAR));
@@ -333,5 +399,5 @@
  *		LoadRegTypeLib	[OLEAUT32.162]
  */
-HRESULT WINAPI LoadRegTypeLib(	
+HRESULT WINAPI LoadRegTypeLib(
 	REFGUID rguid,		/* [in] referenced guid */
 	WORD wVerMajor,		/* [in] major version */
@@ -352,10 +418,10 @@
 
     return res;
-}	
+}
 
 
 /******************************************************************************
  *		RegisterTypeLib	[OLEAUT32.163]
- * Adds information about a type library to the System Registry           
+ * Adds information about a type library to the System Registry
  * NOTES
  *    Docs: ITypeLib FAR * ptlib
@@ -556,5 +622,5 @@
 /******************************************************************************
  *	UnRegisterTypeLib	[OLEAUT32.186]
- * Removes information about a type library from the System Registry           
+ * Removes information about a type library from the System Registry
  * NOTES
  *
@@ -569,5 +635,5 @@
 	LCID lcid,	/* [in] locale id */
 	SYSKIND syskind)
-{   
+{
     TRACE("(IID: %s): stub\n",debugstr_guid(libid));
     return S_OK;	/* FIXME: pretend everything is OK */
@@ -594,5 +660,5 @@
      * to retrieve the "versionForced" info from misc/version.c :(
      * (this would be useful in other places, too) */
-    FIXME("Please report to a.mohr@mailto.de if you get version error messages !\n");
+    FIXME("If you get version error messages, please report them\n");
     switch(GetVersion() & 0x8000ffff)  /* mask off build number */
     {
@@ -616,5 +682,5 @@
 /*======================= ITypeLib implementation =======================*/
 
-typedef struct tagTLBCustData 
+typedef struct tagTLBCustData
 {
     GUID guid;
@@ -649,5 +715,5 @@
     UINT ref;
     TLIBATTR LibAttr;            /* guid,lcid,syskind,version,flags */
-    
+
     /* strings can be stored in tlb as multibyte strings BUT they are *always*
      * exported to the application as a UNICODE string.
@@ -690,5 +756,5 @@
 			       TLB_REF_INTERNAL for internal refs
 			       TLB_REF_NOT_FOUND for broken refs */
-  
+
     struct tagTLBRefType * next;
 } TLBRefType;
@@ -719,5 +785,5 @@
     int ctCustData;
     TLBCustData * pCustData;        /* linked list to cust data; */
-    struct tagTLBFuncDesc * next; 
+    struct tagTLBFuncDesc * next;
 } TLBFuncDesc;
 
@@ -732,5 +798,5 @@
     int ctCustData;
     TLBCustData * pCustData;/* linked list to cust data; */
-    struct tagTLBVarDesc * next; 
+    struct tagTLBVarDesc * next;
 } TLBVarDesc;
 
@@ -753,5 +819,5 @@
     ITypeLibImpl * pTypeLib;        /* back pointer to typelib */
     int index;                  /* index in this typelib; */
-    /* type libs seem to store the doc strings in ascii 
+    /* type libs seem to store the doc strings in ascii
      * so why should we do it in unicode?
      */
@@ -880,5 +946,5 @@
 }
 
-static void dump_ELEMDESC(ELEMDESC *edesc) {
+void dump_ELEMDESC(ELEMDESC *edesc) {
   char buf[200];
   dump_TypeDesc(&edesc->tdesc,buf);
@@ -887,5 +953,5 @@
   MESSAGE("\t\tu.parmadesc.lpex %p\n",edesc->u.paramdesc.pparamdescex);
 }
-static void dump_FUNCDESC(FUNCDESC *funcdesc) {
+void dump_FUNCDESC(FUNCDESC *funcdesc) {
   int i;
   MESSAGE("memid is %08lx\n",funcdesc->memid);
@@ -922,158 +988,7 @@
   MESSAGE("\twFlags: %x\n", funcdesc->wFuncFlags);
 }
-static void dump_TLBFuncDescOne(TLBFuncDesc * pfd)
-{
-  int i;
-  if (!TRACE_ON(typelib))
-      return;
-  MESSAGE("%s(%u)\n", debugstr_w(pfd->Name), pfd->funcdesc.cParams);
-  for (i=0;i<pfd->funcdesc.cParams;i++)
-      MESSAGE("\tparm%d: %s\n",i,debugstr_w(pfd->pParamDesc[i].Name));
-
-
-  dump_FUNCDESC(&(pfd->funcdesc));
-
-  MESSAGE("\thelpstring: %s\n", debugstr_w(pfd->HelpString));
-  MESSAGE("\tentry: %s\n", debugstr_w(pfd->Entry));
-}
-static void dump_TLBFuncDesc(TLBFuncDesc * pfd)
-{
-	while (pfd)
-	{
-	  dump_TLBFuncDescOne(pfd);
-	  pfd = pfd->next;
-	};
-}
-static void dump_TLBVarDesc(TLBVarDesc * pvd)
-{
-	while (pvd)
-	{
-	  TRACE_(typelib)("%s\n", debugstr_w(pvd->Name));
-	  pvd = pvd->next;
-	};
-}
-
-static void dump_TLBImpLib(TLBImpLib *import)
-{
-    TRACE_(typelib)("%s %s\n", debugstr_guid(&(import->guid)),
-		    debugstr_w(import->name));
-    TRACE_(typelib)("v%d.%d lcid=%lx offset=%x\n", import->wVersionMajor,
-		    import->wVersionMinor, import->lcid, import->offset);
-}
-
-static void dump_TLBRefType(TLBRefType * prt)
-{
-	while (prt)
-	{
-	  TRACE_(typelib)("href:0x%08lx\n", prt->reference);
-	  if(prt->index == -1)
-	    TRACE_(typelib)("%s\n", debugstr_guid(&(prt->guid)));
-	  else
-	    TRACE_(typelib)("type no: %d\n", prt->index);
-
-	  if(prt->pImpTLInfo != TLB_REF_INTERNAL &&
-	     prt->pImpTLInfo != TLB_REF_NOT_FOUND) {
-	      TRACE_(typelib)("in lib\n");
-	      dump_TLBImpLib(prt->pImpTLInfo);
-	  }
-	  prt = prt->next;
-	};
-}
-
-static void dump_TLBImplType(TLBImplType * impl)
-{
-    while (impl) {
-        TRACE_(typelib)(
-		"implementing/inheriting interface hRef = %lx implflags %x\n",
-		impl->hRef, impl->implflags);
-	impl = impl->next;
-    }
-}
-      
-static void dump_Variant(VARIANT * pvar)
-{
-    char szVarType[32];
-    LPVOID ref;
-    
-    TRACE("(%p)\n", pvar);
- 
-    if (!pvar)  return;
- 
-    ZeroMemory(szVarType, sizeof(szVarType));
-               
-    /* FIXME : we could have better trace here, depending on the VARTYPE
-     * of the variant
-     */
-    dump_VarType(V_VT(pvar),szVarType);
-
-    TRACE("VARTYPE: %s\n", szVarType);
-
-    if (V_VT(pvar) & VT_BYREF) {
-      ref = V_UNION(pvar, byref);
-      TRACE("%p\n", ref);
-    }
-    else ref = &V_UNION(pvar, cVal);
-
-    if (V_VT(pvar) & VT_ARRAY) {
-      /* FIXME */
-      return;
-    }
-    if (V_VT(pvar) & VT_VECTOR) {
-      /* FIXME */
-      return;
-    }
-
-    switch (V_VT(pvar))
-    {
-        case VT_I2:
-            TRACE("%d\n", *(short*)ref);
-            break;
-
-        case VT_I4:
-            TRACE("%d\n", *(INT*)ref);
-            break;
-
-        case VT_R4:
-            TRACE("%3.3e\n", *(float*)ref);
-            break;
-
-        case VT_R8:
-            TRACE("%3.3e\n", *(double*)ref);
-            break;
-
-        case VT_BOOL:
-            TRACE("%s\n", *(VARIANT_BOOL*)ref ? "TRUE" : "FALSE");
-            break;
-
-        case VT_BSTR:
-            TRACE("%s\n", debugstr_w(*(BSTR*)ref));
-            break;
-
-        case VT_UNKNOWN:
-        case VT_DISPATCH:
-            TRACE("%p\n", *(LPVOID*)ref);
-            break;
-
-        case VT_VARIANT:
-            if (V_VT(pvar) & VT_BYREF) dump_Variant(ref);
-            break;
-
-        default:
-            TRACE("(?)%ld\n", *(long*)ref);
-            break;
-    }       
-}
-
-static void dump_DispParms(DISPPARAMS * pdp)
-{
-    int index = 0;
-    
-    TRACE("args=%u named args=%u\n", pdp->cArgs, pdp->cNamedArgs);
-
-    while (index < pdp->cArgs)
-    {
-        dump_Variant( &pdp->rgvarg[index] );
-        ++index;
-    }
+
+void dump_IDLDESC(IDLDESC *idl) {
+  MESSAGE("\t\twIdlflags: %d\n",idl->wIDLFlags);
 }
 
@@ -1091,4 +1006,201 @@
 };
 
+void dump_TYPEATTR(TYPEATTR *tattr) {
+  char buf[200];
+  MESSAGE("\tguid: %s\n",debugstr_guid(&tattr->guid));
+  MESSAGE("\tlcid: %ld\n",tattr->lcid);
+  MESSAGE("\tmemidConstructor: %ld\n",tattr->memidConstructor);
+  MESSAGE("\tmemidDestructor: %ld\n",tattr->memidDestructor);
+  MESSAGE("\tschema: %s\n",debugstr_w(tattr->lpstrSchema));
+  MESSAGE("\tsizeInstance: %ld\n",tattr->cbSizeInstance);
+  MESSAGE("\tkind:%s\n", typekind_desc[tattr->typekind]);
+  MESSAGE("\tcFuncs: %d\n", tattr->cFuncs);
+  MESSAGE("\tcVars: %d\n", tattr->cVars);
+  MESSAGE("\tcImplTypes: %d\n", tattr->cImplTypes);
+  MESSAGE("\tcbSizeVft: %d\n", tattr->cbSizeVft);
+  MESSAGE("\tcbAlignment: %d\n", tattr->cbAlignment);
+  MESSAGE("\twTypeFlags: %d\n", tattr->wTypeFlags);
+  MESSAGE("\tVernum: %d.%d\n", tattr->wMajorVerNum,tattr->wMinorVerNum);
+  dump_TypeDesc(&tattr->tdescAlias,buf);
+  MESSAGE("\ttypedesc: %s\n", buf);
+  dump_IDLDESC(&tattr->idldescType);
+}
+
+static void dump_TLBFuncDescOne(TLBFuncDesc * pfd)
+{
+  int i;
+  if (!TRACE_ON(typelib))
+      return;
+  MESSAGE("%s(%u)\n", debugstr_w(pfd->Name), pfd->funcdesc.cParams);
+  for (i=0;i<pfd->funcdesc.cParams;i++)
+      MESSAGE("\tparm%d: %s\n",i,debugstr_w(pfd->pParamDesc[i].Name));
+
+
+  dump_FUNCDESC(&(pfd->funcdesc));
+
+  MESSAGE("\thelpstring: %s\n", debugstr_w(pfd->HelpString));
+  MESSAGE("\tentry: %s\n", debugstr_w(pfd->Entry));
+}
+static void dump_TLBFuncDesc(TLBFuncDesc * pfd)
+{
+	while (pfd)
+	{
+	  dump_TLBFuncDescOne(pfd);
+	  pfd = pfd->next;
+	};
+}
+static void dump_TLBVarDesc(TLBVarDesc * pvd)
+{
+	while (pvd)
+	{
+	  TRACE_(typelib)("%s\n", debugstr_w(pvd->Name));
+	  pvd = pvd->next;
+	};
+}
+
+static void dump_TLBImpLib(TLBImpLib *import)
+{
+    TRACE_(typelib)("%s %s\n", debugstr_guid(&(import->guid)),
+		    debugstr_w(import->name));
+    TRACE_(typelib)("v%d.%d lcid=%lx offset=%x\n", import->wVersionMajor,
+		    import->wVersionMinor, import->lcid, import->offset);
+}
+
+static void dump_TLBRefType(TLBRefType * prt)
+{
+	while (prt)
+	{
+	  TRACE_(typelib)("href:0x%08lx\n", prt->reference);
+	  if(prt->index == -1)
+	    TRACE_(typelib)("%s\n", debugstr_guid(&(prt->guid)));
+	  else
+	    TRACE_(typelib)("type no: %d\n", prt->index);
+
+	  if(prt->pImpTLInfo != TLB_REF_INTERNAL &&
+	     prt->pImpTLInfo != TLB_REF_NOT_FOUND) {
+	      TRACE_(typelib)("in lib\n");
+	      dump_TLBImpLib(prt->pImpTLInfo);
+	  }
+	  prt = prt->next;
+	};
+}
+
+static void dump_TLBImplType(TLBImplType * impl)
+{
+    while (impl) {
+        TRACE_(typelib)(
+		"implementing/inheriting interface hRef = %lx implflags %x\n",
+		impl->hRef, impl->implflags);
+	impl = impl->next;
+    }
+}
+
+void dump_Variant(VARIANT * pvar)
+{
+    char szVarType[32];
+    LPVOID ref;
+
+    TRACE("(%p)\n", pvar);
+
+    if (!pvar)  return;
+
+    ZeroMemory(szVarType, sizeof(szVarType));
+
+    /* FIXME : we could have better trace here, depending on the VARTYPE
+     * of the variant
+     */
+    dump_VarType(V_VT(pvar),szVarType);
+
+    TRACE("VARTYPE: %s\n", szVarType);
+
+    if (V_VT(pvar) & VT_BYREF) {
+      ref = V_UNION(pvar, byref);
+      TRACE("%p\n", ref);
+    }
+    else ref = &V_UNION(pvar, cVal);
+
+    if (V_VT(pvar) & VT_ARRAY) {
+      /* FIXME */
+      return;
+    }
+    if (V_VT(pvar) & VT_VECTOR) {
+      /* FIXME */
+      return;
+    }
+
+    switch (V_VT(pvar) & VT_TYPEMASK)
+    {
+        case VT_I2:
+            TRACE("%d\n", *(short*)ref);
+            break;
+
+        case VT_I4:
+            TRACE("%d\n", *(INT*)ref);
+            break;
+
+        case VT_R4:
+            TRACE("%3.3e\n", *(float*)ref);
+            break;
+
+        case VT_R8:
+            TRACE("%3.3e\n", *(double*)ref);
+            break;
+
+        case VT_BOOL:
+            TRACE("%s\n", *(VARIANT_BOOL*)ref ? "TRUE" : "FALSE");
+            break;
+
+        case VT_BSTR:
+            TRACE("%s\n", debugstr_w(*(BSTR*)ref));
+            break;
+
+        case VT_UNKNOWN:
+        case VT_DISPATCH:
+            TRACE("%p\n", *(LPVOID*)ref);
+            break;
+
+        case VT_VARIANT:
+            if (V_VT(pvar) & VT_BYREF) dump_Variant(ref);
+            break;
+
+        case VT_DATE:
+        {
+            struct tm TM;
+            memset( &TM, 0, sizeof(TM) );
+
+            if( DateToTm( *(DATE*)ref, 0, &TM ) == FALSE ) {
+                TRACE("invalid date? (?)%ld %f\n", *(long*)ref, *(double *)ref);
+            } else {
+                TRACE("(yyyymmdd) %4.4d-%2.2d-%2.2d (time) %2.2d:%2.2d:%2.2d [%f]\n",
+                       TM.tm_year, TM.tm_mon+1, TM.tm_mday,
+                      TM.tm_hour, TM.tm_min, TM.tm_sec, *(double *)ref);
+            }
+            break;
+        }
+
+        case VT_CY:
+            TRACE("%ld (hi), %lu (lo)\n", ((CY *)ref)->s.Hi, ((CY *)ref)->s.Lo);
+            break;
+
+
+        default:
+            TRACE("(?)%ld\n", *(long*)ref);
+            break;
+    }
+}
+
+static void dump_DispParms(DISPPARAMS * pdp)
+{
+    int index = 0;
+
+    TRACE("args=%u named args=%u\n", pdp->cArgs, pdp->cNamedArgs);
+
+    while (index < pdp->cArgs)
+    {
+        dump_Variant( &pdp->rgvarg[index] );
+        ++index;
+    }
+}
+
 static void dump_TypeInfo(ITypeInfoImpl * pty)
 {
@@ -1103,4 +1215,14 @@
     dump_TLBVarDesc(pty->varlist);
     dump_TLBImplType(pty->impltypelist);
+}
+
+void dump_VARDESC(VARDESC *v)
+{
+    MESSAGE("memid %ld\n",v->memid);
+    MESSAGE("lpstrSchema %s\n",debugstr_w(v->lpstrSchema));
+    MESSAGE("oInst %ld\n",v->u.oInst);
+    dump_ELEMDESC(&(v->elemdescVar));
+    MESSAGE("wVarFlags %x\n",v->wVarFlags);
+    MESSAGE("varkind %d\n",v->varkind);
 }
 #else
@@ -1124,5 +1246,5 @@
 #define  dump_TLBFuncDesc(a)
 #define  dump_TypeDesc(a,b)
-#define  dump_Variant(a)
+#define  dump_VARDESC(a)
 #define  debugstr_an(a,b) NULL
 #endif
@@ -1188,8 +1310,28 @@
 }
 
+static DWORD MSFT_ReadLEDWords(void *buffer,  DWORD count, TLBContext *pcx,
+			       long where )
+{
+  DWORD ret;
+
+  ret = MSFT_Read(buffer, count, pcx, where);
+  FromLEDWords(buffer, ret);
+
+  return ret;
+}
+
+static DWORD MSFT_ReadLEWords(void *buffer,  DWORD count, TLBContext *pcx,
+			      long where )
+{
+  DWORD ret;
+
+  ret = MSFT_Read(buffer, count, pcx, where);
+  FromLEWords(buffer, ret);
+
+  return ret;
+}
+
 static void MSFT_ReadGuid( GUID *pGuid, int offset, TLBContext *pcx)
 {
-    TRACE_(typelib)("%s\n", debugstr_guid(pGuid));
-
     if(offset<0 || pcx->pTblDir->pGuidTab.offset <0){
         memset(pGuid,0, sizeof(GUID));
@@ -1197,4 +1339,8 @@
     }
     MSFT_Read(pGuid, sizeof(GUID), pcx, pcx->pTblDir->pGuidTab.offset+offset );
+    pGuid->Data1 = FromLEDWord(pGuid->Data1);
+    pGuid->Data2 = FromLEWord(pGuid->Data2);
+    pGuid->Data3 = FromLEWord(pGuid->Data3);
+    TRACE_(typelib)("%s\n", debugstr_guid(pGuid));
 }
 
@@ -1207,6 +1353,6 @@
     BSTR bstrName = NULL;
 
-    MSFT_Read(&niName, sizeof(niName), pcx,
-				pcx->pTblDir->pNametab.offset+offset);
+    MSFT_ReadLEDWords(&niName, sizeof(niName), pcx,
+		      pcx->pTblDir->pNametab.offset+offset);
     niName.namelen &= 0xFF; /* FIXME: correct ? */
     name=TLB_Alloc((niName.namelen & 0xff) +1);
@@ -1242,5 +1388,5 @@
 
     if(offset<0) return NULL;
-    MSFT_Read(&length, sizeof(INT16), pcx, pcx->pTblDir->pStringtab.offset+offset);
+    MSFT_ReadLEWords(&length, sizeof(INT16), pcx, pcx->pTblDir->pStringtab.offset+offset);
     if(length <= 0) return 0;
     string=TLB_Alloc(length +1);
@@ -1268,5 +1414,5 @@
 }
 /*
- * read a value and fill a VARIANT structure 
+ * read a value and fill a VARIANT structure
  */
 static void MSFT_ReadValue( VARIANT * pVar, int offset, TLBContext *pcx )
@@ -1281,6 +1427,6 @@
         return;
     }
-    MSFT_Read(&(V_VT(pVar)), sizeof(VARTYPE), pcx, 
-        pcx->pTblDir->pCustData.offset + offset );
+    MSFT_ReadLEWords(&(V_VT(pVar)), sizeof(VARTYPE), pcx,
+                     pcx->pTblDir->pCustData.offset + offset );
     TRACE_(typelib)("Vartype = %x\n", V_VT(pVar));
     switch (V_VT(pVar)){
@@ -1290,20 +1436,20 @@
         case VT_I4  :
         case VT_R4  :
-        case VT_ERROR   : 
-        case VT_BOOL    : 
-        case VT_I1  : 
-        case VT_UI1 : 
-        case VT_UI2 : 
-        case VT_UI4 : 
-        case VT_INT : 
-        case VT_UINT    : 
+        case VT_ERROR   :
+        case VT_BOOL    :
+        case VT_I1  :
+        case VT_UI1 :
+        case VT_UI2 :
+        case VT_UI4 :
+        case VT_INT :
+        case VT_UINT    :
         case VT_VOID    : /* FIXME: is this right? */
-        case VT_HRESULT : 
+        case VT_HRESULT :
             size=4; break;
         case VT_R8  :
         case VT_CY  :
-        case VT_DATE    : 
-        case VT_I8  : 
-        case VT_UI8 : 
+        case VT_DATE    :
+        case VT_I8  :
+        case VT_UI8 :
         case VT_DECIMAL :  /* FIXME: is this right? */
         case VT_FILETIME :
@@ -1312,5 +1458,5 @@
         case VT_BSTR    :{
             char * ptr;
-            MSFT_Read(&size, sizeof(INT), pcx, DO_NOT_SEEK );
+            MSFT_ReadLEDWords(&size, sizeof(INT), pcx, DO_NOT_SEEK );
 	    if(size <= 0) {
 	        FIXME("BSTR length = %d?\n", size);
@@ -1328,22 +1474,22 @@
     /* FIXME: this will not work AT ALL when the variant contains a pointer */
         case VT_DISPATCH :
-        case VT_VARIANT : 
-        case VT_UNKNOWN : 
-        case VT_PTR : 
+        case VT_VARIANT :
+        case VT_UNKNOWN :
+        case VT_PTR :
         case VT_SAFEARRAY :
-        case VT_CARRAY  : 
-        case VT_USERDEFINED : 
-        case VT_LPSTR   : 
-        case VT_LPWSTR  : 
-        case VT_BLOB    : 
-        case VT_STREAM  : 
-        case VT_STORAGE : 
-        case VT_STREAMED_OBJECT : 
-        case VT_STORED_OBJECT   : 
-        case VT_BLOB_OBJECT : 
-        case VT_CF  : 
-        case VT_CLSID   : 
-        default: 
-            size=0; 
+        case VT_CARRAY  :
+        case VT_USERDEFINED :
+        case VT_LPSTR   :
+        case VT_LPWSTR  :
+        case VT_BLOB    :
+        case VT_STREAM  :
+        case VT_STORAGE :
+        case VT_STREAMED_OBJECT :
+        case VT_STORED_OBJECT   :
+        case VT_BLOB_OBJECT :
+        case VT_CF  :
+        case VT_CLSID   :
+        default:
+            size=0;
             FIXME("VARTYPE %d is not supported, setting pointer to NULL\n",
                 V_VT(pVar));
@@ -1368,6 +1514,5 @@
         count++;
         pNew=TLB_Alloc(sizeof(TLBCustData));
-        MSFT_Read(&entry, sizeof(entry), pcx, 
-            pcx->pTblDir->pCDGuids.offset+offset);
+        MSFT_ReadLEDWords(&entry, sizeof(entry), pcx, pcx->pTblDir->pCDGuids.offset+offset);
         MSFT_ReadGuid(&(pNew->guid), entry.GuidOffset , pcx);
         MSFT_ReadValue(&(pNew->data), entry.DataOffset, pcx);
@@ -1394,23 +1539,23 @@
 }
 
-static void 
+static void
 MSFT_DoFuncs(TLBContext*     pcx,
 	    ITypeInfoImpl*  pTI,
-            int             cFuncs, 
+            int             cFuncs,
             int             cVars,
-            int             offset, 
+            int             offset,
             TLBFuncDesc**   pptfd)
 {
-    /* 
+    /*
      * member information is stored in a data structure at offset
      * indicated by the memoffset field of the typeinfo structure
      * There are several distinctive parts.
-     * the first part starts with a field that holds the total length 
+     * the first part starts with a field that holds the total length
      * of this (first) part excluding this field. Then follow the records,
      * for each member there is one record.
      *
      * First entry is always the length of the record (excluding this
-     * length word). 
-     * Rest of the record depends on the type of the member. If there is 
+     * length word).
+     * Rest of the record depends on the type of the member. If there is
      * a field indicating the member type (function variable intereface etc)
      * I have not found it yet. At this time we depend on the information
@@ -1419,8 +1564,8 @@
      * Second follows an array sized nrMEM*sizeof(INT) with a memeber id
      * for each member;
-     * 
-     * Third is a equal sized array with file offsets to the name entry 
+     *
+     * Third is a equal sized array with file offsets to the name entry
      * of each member.
-     * 
+     *
      * Forth and last (?) part is an array with offsets to the records in the
      * first part of this file segment.
@@ -1435,5 +1580,5 @@
     TRACE_(typelib)("\n");
 
-    MSFT_Read(&infolen, sizeof(INT), pcx, offset);
+    MSFT_ReadLEDWords(&infolen, sizeof(INT), pcx, offset);
 
     for ( i = 0; i < cFuncs ; i++ )
@@ -1442,17 +1587,15 @@
 
         /* name, eventually add to a hash table */
-        MSFT_Read(&nameoffset, 
-                 sizeof(INT), 
-                 pcx, 
-                 offset + infolen + (cFuncs + cVars + i + 1) * sizeof(INT));
+        MSFT_ReadLEDWords(&nameoffset, sizeof(INT), pcx,
+                          offset + infolen + (cFuncs + cVars + i + 1) * sizeof(INT));
 
         (*pptfd)->Name = MSFT_ReadName(pcx, nameoffset);
 
         /* read the function information record */
-        MSFT_Read(&reclength, sizeof(INT), pcx, recoffset);
-        
+        MSFT_ReadLEDWords(&reclength, sizeof(INT), pcx, recoffset);
+
         reclength &= 0x1ff;
 
-        MSFT_Read(pFuncRec, reclength - sizeof(INT), pcx, DO_NOT_SEEK) ; 
+        MSFT_ReadLEDWords(pFuncRec, reclength - sizeof(INT), pcx, DO_NOT_SEEK);
 
         /* do the attributes */
@@ -1463,5 +1606,5 @@
         {
             (*pptfd)->helpcontext = pFuncRec->OptAttr[0] ;
-            
+
             if ( nrattributes > 1 )
             {
@@ -1486,5 +1629,5 @@
                         if ( nrattributes > 6 && pFuncRec->FKCCIC & 0x80 )
                         {
-                            MSFT_CustData(pcx, 
+                            MSFT_CustData(pcx,
 					  pFuncRec->OptAttr[6],
 					  &(*pptfd)->pCustData);
@@ -1496,7 +1639,6 @@
 
         /* fill the FuncDesc Structure */
-        MSFT_Read( & (*pptfd)->funcdesc.memid, 
-                  sizeof(INT), pcx, 
-                  offset + infolen + ( i + 1) * sizeof(INT));
+        MSFT_ReadLEDWords( & (*pptfd)->funcdesc.memid, sizeof(INT), pcx,
+                           offset + infolen + ( i + 1) * sizeof(INT));
 
         (*pptfd)->funcdesc.funckind   =  (pFuncRec->FKCCIC)      & 0x7;
@@ -1508,6 +1650,6 @@
         (*pptfd)->funcdesc.wFuncFlags =   LOWORD(pFuncRec->Flags) ;
 
-        MSFT_GetTdesc(pcx, 
-		      pFuncRec->DataType,   
+        MSFT_GetTdesc(pcx,
+		      pFuncRec->DataType,
 		      &(*pptfd)->funcdesc.elemdescFunc.tdesc,
 		      pTI);
@@ -1519,15 +1661,12 @@
             MSFT_ParameterInfo paraminfo;
 
-            (*pptfd)->funcdesc.lprgelemdescParam = 
+            (*pptfd)->funcdesc.lprgelemdescParam =
                 TLB_Alloc(pFuncRec->nrargs * sizeof(ELEMDESC));
 
-            (*pptfd)->pParamDesc = 
+            (*pptfd)->pParamDesc =
                 TLB_Alloc(pFuncRec->nrargs * sizeof(TLBParDesc));
 
-            MSFT_Read(&paraminfo,
-		      sizeof(paraminfo), 
-		      pcx, 
-		      recoffset + reclength -
-		      pFuncRec->nrargs * sizeof(MSFT_ParameterInfo));
+            MSFT_ReadLEDWords(&paraminfo, sizeof(paraminfo), pcx,
+                              recoffset + reclength - pFuncRec->nrargs * sizeof(MSFT_ParameterInfo));
 
             for ( j = 0 ; j < pFuncRec->nrargs ; j++ )
@@ -1535,6 +1674,6 @@
                 TYPEDESC* lpArgTypeDesc = 0;
 
-                MSFT_GetTdesc(pcx, 
-			      paraminfo.DataType,   
+                MSFT_GetTdesc(pcx,
+			      paraminfo.DataType,
 			      &(*pptfd)->funcdesc.lprgelemdescParam[j].tdesc,
 			      pTI);
@@ -1544,13 +1683,13 @@
                 (*pptfd)->pParamDesc[j].Name = (void *) paraminfo.oName;
 
-                /* SEEK value = jump to offset, 
+                /* SEEK value = jump to offset,
                  * from there jump to the end of record,
                  * go back by (j-1) arguments
                  */
-                MSFT_Read( &paraminfo ,
+                MSFT_ReadLEDWords( &paraminfo ,
 			   sizeof(MSFT_ParameterInfo), pcx,
-			   recoffset + reclength - ((pFuncRec->nrargs - j - 1) 
+			   recoffset + reclength - ((pFuncRec->nrargs - j - 1)
 					       * sizeof(MSFT_ParameterInfo)));
-                lpArgTypeDesc = 
+                lpArgTypeDesc =
                     & ((*pptfd)->funcdesc.lprgelemdescParam[j].tdesc);
 
@@ -1568,5 +1707,5 @@
 
                     case VT_USERDEFINED:
-                        MSFT_DoRefType(pcx, pTI, 
+                        MSFT_DoRefType(pcx, pTI,
 				       lpArgTypeDesc->u.hreftype);
 
@@ -1586,5 +1725,5 @@
                 TYPEDESC* lpArgTypeDesc;
 
-                (*pptfd)->funcdesc.elemdescFunc = 
+                (*pptfd)->funcdesc.elemdescFunc =
                 (*pptfd)->funcdesc.lprgelemdescParam[j];
 
@@ -1599,5 +1738,5 @@
                         break;
                     case VT_CARRAY:
-                        lpArgTypeDesc = 
+                        lpArgTypeDesc =
                         & (lpArgTypeDesc->u.lpadesc->tdescElem);
 
@@ -1605,5 +1744,5 @@
 
                     case VT_USERDEFINED:
-                        MSFT_DoRefType(pcx, 
+                        MSFT_DoRefType(pcx,
 				       pTI,
 				       lpArgTypeDesc->u.hreftype);
@@ -1626,10 +1765,10 @@
 
                 /* default value */
-                if ( (PARAMFLAG_FHASDEFAULT & 
+                if ( (PARAMFLAG_FHASDEFAULT &
                       (*pptfd)->funcdesc.lprgelemdescParam[j].u.paramdesc.wParamFlags) &&
                      ((pFuncRec->FKCCIC) & 0x1000) )
                 {
-                    INT* pInt = (INT *)((char *)pFuncRec + 
-                                   reclength - 
+                    INT* pInt = (INT *)((char *)pFuncRec +
+                                   reclength -
                                    (pFuncRec->nrargs * 4 + 1) * sizeof(INT) );
 
@@ -1639,5 +1778,5 @@
                     pParamDesc->pparamdescex->cBytes = sizeof(PARAMDESCEX);
 
-		    MSFT_ReadValue(&(pParamDesc->pparamdescex->varDefaultValue), 
+		    MSFT_ReadValue(&(pParamDesc->pparamdescex->varDefaultValue),
                         pInt[j], pcx);
                 }
@@ -1645,5 +1784,5 @@
                 if ( nrattributes > 7 + j && pFuncRec->FKCCIC & 0x80 )
                 {
-                    MSFT_CustData(pcx, 
+                    MSFT_CustData(pcx,
 				  pFuncRec->OptAttr[7+j],
 				  &(*pptfd)->pParamDesc[j].pCustData);
@@ -1671,18 +1810,18 @@
     TRACE_(typelib)("\n");
 
-    MSFT_Read(&infolen,sizeof(INT), pcx, offset);
-    MSFT_Read(&recoffset,sizeof(INT), pcx, offset + infolen + 
-        ((cFuncs+cVars)*2+cFuncs + 1)*sizeof(INT));
+    MSFT_ReadLEDWords(&infolen,sizeof(INT), pcx, offset);
+    MSFT_ReadLEDWords(&recoffset,sizeof(INT), pcx, offset + infolen +
+                      ((cFuncs+cVars)*2+cFuncs + 1)*sizeof(INT));
     recoffset += offset+sizeof(INT);
     for(i=0;i<cVars;i++){
         *pptvd=TLB_Alloc(sizeof(TLBVarDesc));
     /* name, eventually add to a hash table */
-        MSFT_Read(&nameoffset, sizeof(INT), pcx, 
-            offset + infolen + (cFuncs + cVars + i + 1) * sizeof(INT));
+        MSFT_ReadLEDWords(&nameoffset, sizeof(INT), pcx,
+                          offset + infolen + (cFuncs + cVars + i + 1) * sizeof(INT));
         (*pptvd)->Name=MSFT_ReadName(pcx, nameoffset);
     /* read the variable information record */
-        MSFT_Read(&reclength, sizeof(INT), pcx, recoffset);
+        MSFT_ReadLEDWords(&reclength, sizeof(INT), pcx, recoffset);
         reclength &=0xff;
-        MSFT_Read(pVarRec, reclength - sizeof(INT), pcx, DO_NOT_SEEK) ; 
+        MSFT_ReadLEDWords(pVarRec, reclength - sizeof(INT), pcx, DO_NOT_SEEK);
     /* Optional data */
         if(reclength >(6*sizeof(INT)) )
@@ -1694,9 +1833,9 @@
             (*pptvd)->HelpStringContext=pVarRec->HelpStringContext;
     /* fill the VarDesc Structure */
-        MSFT_Read(&(*pptvd)->vardesc.memid, sizeof(INT), pcx, 
-            offset + infolen + ( i + 1) * sizeof(INT));
+        MSFT_ReadLEDWords(&(*pptvd)->vardesc.memid, sizeof(INT), pcx,
+                          offset + infolen + ( i + 1) * sizeof(INT));
         (*pptvd)->vardesc.varkind = pVarRec->VarKind;
         (*pptvd)->vardesc.wVarFlags = pVarRec->Flags;
-        MSFT_GetTdesc(pcx, pVarRec->DataType,    
+        MSFT_GetTdesc(pcx, pVarRec->DataType,
             &(*pptvd)->vardesc.elemdescVar.tdesc, pTI);
 /*   (*pptvd)->vardesc.lpstrSchema; is reserved (SDK) FIXME?? */
@@ -1739,6 +1878,6 @@
         TRACE_(typelib)("offset %x, masked offset %x\n", offset, offset + (offset & 0xfffffffc));
 
-        MSFT_Read(&impinfo, sizeof(impinfo), pcx, 
-            pcx->pTblDir->pImpInfo.offset + (offset & 0xfffffffc));
+        MSFT_ReadLEDWords(&impinfo, sizeof(impinfo), pcx,
+                          pcx->pTblDir->pImpInfo.offset + (offset & 0xfffffffc));
         for(j=0;pImpLib;j++){   /* search the known offsets of all import libraries */
             if(pImpLib->offset==impinfo.oImpFile) break;
@@ -1776,6 +1915,6 @@
         if(offset<0) break; /* paranoia */
         *ppImpl=TLB_Alloc(sizeof(**ppImpl));
-        MSFT_Read(&refrec,sizeof(refrec),pcx,offset+pcx->pTblDir->pRefTab.offset);
-        MSFT_DoRefType(pcx, pTI, refrec.reftype); 
+        MSFT_ReadLEDWords(&refrec,sizeof(refrec),pcx,offset+pcx->pTblDir->pRefTab.offset);
+        MSFT_DoRefType(pcx, pTI, refrec.reftype);
 	(*ppImpl)->hRef = refrec.reftype;
 	(*ppImpl)->implflags=refrec.flags;
@@ -1800,6 +1939,6 @@
 
     ptiRet = (ITypeInfoImpl*) ITypeInfo_Constructor();
-    MSFT_Read(&tiBase, sizeof(tiBase) ,pcx ,
-        pcx->pTblDir->pTypeInfoTab.offset+count*sizeof(tiBase));
+    MSFT_ReadLEDWords(&tiBase, sizeof(tiBase) ,pcx ,
+                      pcx->pTblDir->pTypeInfoTab.offset+count*sizeof(tiBase));
 /* this is where we are coming from */
     ptiRet->pTypeLib = pLibInfo;
@@ -1825,5 +1964,5 @@
     ptiRet->TypeAttr.cbSizeVft=tiBase.cbSizeVft; /* FIXME: this is only the non inherited part */
     if(ptiRet->TypeAttr.typekind == TKIND_ALIAS)
-        MSFT_GetTdesc(pcx, tiBase.datatype1, 
+        MSFT_GetTdesc(pcx, tiBase.datatype1,
             &ptiRet->TypeAttr.tdescAlias, ptiRet);
 
@@ -1844,10 +1983,10 @@
     if(ptiRet->TypeAttr.cFuncs >0 )
         MSFT_DoFuncs(pcx, ptiRet, ptiRet->TypeAttr.cFuncs,
-		    ptiRet->TypeAttr.cVars, 
+		    ptiRet->TypeAttr.cVars,
 		    tiBase.memoffset, & ptiRet->funclist);
     /* variables */
     if(ptiRet->TypeAttr.cVars >0 )
         MSFT_DoVars(pcx, ptiRet, ptiRet->TypeAttr.cFuncs,
-		   ptiRet->TypeAttr.cVars, 
+		   ptiRet->TypeAttr.cVars,
 		   tiBase.memoffset, & ptiRet->varlist);
     if(ptiRet->TypeAttr.cImplTypes >0 ) {
@@ -1855,10 +1994,10 @@
         {
         case TKIND_COCLASS:
-            MSFT_DoImplTypes(pcx, ptiRet, ptiRet->TypeAttr.cImplTypes , 
+            MSFT_DoImplTypes(pcx, ptiRet, ptiRet->TypeAttr.cImplTypes ,
                 tiBase.datatype1);
             break;
         case TKIND_DISPATCH:
             ptiRet->impltypelist=TLB_Alloc(sizeof(TLBImplType));
-            
+
             if (tiBase.datatype1 != -1)
             {
@@ -1883,8 +2022,8 @@
 		(*ppRef)->index            = TLB_REF_USE_GUID;
 		(*ppRef)->pImpTLInfo       = TLB_Alloc(sizeof(TLBImpLib));
-		(*ppRef)->pImpTLInfo->guid = IID_StdOle;             
+		(*ppRef)->pImpTLInfo->guid = IID_StdOle;
 		(*ppRef)->pImpTLInfo->name = SysAllocStringLen(NULL,
 							      nStdOleLen  + 1);
-              
+
 		MultiByteToWideChar(CP_ACP,
 				    MB_PRECOMPOSED,
@@ -1893,5 +2032,5 @@
 				    (*ppRef)->pImpTLInfo->name,
 				    SysStringLen((*ppRef)->pImpTLInfo->name));
-                                  
+
 		(*ppRef)->pImpTLInfo->lcid          = 0;
 		(*ppRef)->pImpTLInfo->wVersionMajor = 2;
@@ -1930,5 +2069,5 @@
     int ret = TYPE_E_CANTLOADLIBRARY;
     DWORD dwSignature = 0;
-    HFILE hFile;
+    HANDLE hFile;
 
     TRACE_(typelib)("%s:%d\n", debugstr_w(pszFileName), index);
@@ -1950,5 +2089,5 @@
 
           /* first try to load as *.tlb */
-          dwSignature = *((DWORD*) pBase);
+          dwSignature = FromLEDWord(*((DWORD*) pBase));
           if ( dwSignature == MSFT_SIGNATURE)
           {
@@ -1982,9 +2121,9 @@
             LPVOID pBase = LockResource(hGlobal);
             DWORD  dwTLBLength = SizeofResource(hinstDLL, hrsrc);
-            
+
             if (pBase)
             {
               /* try to load as incore resource */
-              dwSignature = *((DWORD*) pBase);
+              dwSignature = FromLEDWord(*((DWORD*) pBase));
               if ( dwSignature == MSFT_SIGNATURE)
               {
@@ -2045,10 +2184,10 @@
     cx.pLibInfo = pTypeLibImpl;
     cx.length = dwTLBLength;
-    
+
     /* read header */
-    MSFT_Read((void*)&tlbHeader, sizeof(tlbHeader), &cx, 0);
+    MSFT_ReadLEDWords((void*)&tlbHeader, sizeof(tlbHeader), &cx, 0);
     TRACE("header:\n");
     TRACE("\tmagic1=0x%08x ,magic2=0x%08x\n",tlbHeader.magic1,tlbHeader.magic2 );
-    if (memcmp(&tlbHeader.magic1,TLBMAGIC2,4)) {
+    if (tlbHeader.magic1 != MSFT_SIGNATURE) {
 	FIXME("Header type magic 0x%08x not supported.\n",tlbHeader.magic1);
 	return NULL;
@@ -2061,5 +2200,5 @@
     /* now read the segment directory */
     TRACE("read segment directory (at %ld)\n",lPSegDir);
-    MSFT_Read((void*)&tlbSegDir, sizeof(tlbSegDir), &cx, lPSegDir);  
+    MSFT_ReadLEDWords(&tlbSegDir, sizeof(tlbSegDir), &cx, lPSegDir);
     cx.pTblDir = &tlbSegDir;
 
@@ -2098,5 +2237,5 @@
     {
             int offset;
-            MSFT_Read(&offset, sizeof(offset), &cx, sizeof(tlbHeader));
+            MSFT_ReadLEDWords(&offset, sizeof(offset), &cx, sizeof(tlbHeader));
             pTypeLibImpl->HelpStringDll = MSFT_ReadString(&cx, offset);
     }
@@ -2116,5 +2255,5 @@
         INT16 td[4];
         pTypeLibImpl->pTypeDesc = TLB_Alloc( cTD * sizeof(TYPEDESC));
-        MSFT_Read(td, sizeof(td), &cx, tlbSegDir.pTypdescTab.offset);
+        MSFT_ReadLEWords(td, sizeof(td), &cx, tlbSegDir.pTypdescTab.offset);
         for(i=0; i<cTD; )
 	{
@@ -2138,5 +2277,5 @@
                 pTypeLibImpl->pTypeDesc[i].u.hreftype = MAKELONG(td[2],td[3]);
             }
-	    if(++i<cTD) MSFT_Read(td, sizeof(td), &cx, DO_NOT_SEEK);
+	    if(++i<cTD) MSFT_ReadLEWords(td, sizeof(td), &cx, DO_NOT_SEEK);
         }
 
@@ -2147,5 +2286,5 @@
             if(tlbSegDir.pArrayDescriptions.offset>0)
 	    {
-                MSFT_Read(td, sizeof(td), &cx, tlbSegDir.pArrayDescriptions.offset + (int) pTypeLibImpl->pTypeDesc[i].u.lpadesc);
+                MSFT_ReadLEWords(td, sizeof(td), &cx, tlbSegDir.pArrayDescriptions.offset + (int) pTypeLibImpl->pTypeDesc[i].u.lpadesc);
                 pTypeLibImpl->pTypeDesc[i].u.lpadesc = TLB_Alloc(sizeof(ARRAYDESC)+sizeof(SAFEARRAYBOUND)*(td[3]-1));
 
@@ -2159,8 +2298,8 @@
                 for(j = 0; j<td[2]; j++)
 		{
-                    MSFT_Read(& pTypeLibImpl->pTypeDesc[i].u.lpadesc->rgbounds[j].cElements, 
-                        sizeof(INT), &cx, DO_NOT_SEEK);
-                    MSFT_Read(& pTypeLibImpl->pTypeDesc[i].u.lpadesc->rgbounds[j].lLbound, 
-                        sizeof(INT), &cx, DO_NOT_SEEK);
+                    MSFT_ReadLEDWords(& pTypeLibImpl->pTypeDesc[i].u.lpadesc->rgbounds[j].cElements,
+                                      sizeof(INT), &cx, DO_NOT_SEEK);
+                    MSFT_ReadLEDWords(& pTypeLibImpl->pTypeDesc[i].u.lpadesc->rgbounds[j].lLbound,
+                                      sizeof(INT), &cx, DO_NOT_SEEK);
                 }
             }
@@ -2184,10 +2323,10 @@
             *ppImpLib = TLB_Alloc(sizeof(TLBImpLib));
             (*ppImpLib)->offset = offset - tlbSegDir.pImpFiles.offset;
-            MSFT_Read(&oGuid, sizeof(INT), &cx, offset);
-
-	    MSFT_Read(&(*ppImpLib)->lcid,          sizeof(LCID),   &cx, DO_NOT_SEEK);
-            MSFT_Read(&(*ppImpLib)->wVersionMajor, sizeof(WORD),   &cx, DO_NOT_SEEK);
-            MSFT_Read(&(*ppImpLib)->wVersionMinor, sizeof(WORD),   &cx, DO_NOT_SEEK);
-            MSFT_Read(& size,                      sizeof(UINT16), &cx, DO_NOT_SEEK);
+            MSFT_ReadLEDWords(&oGuid, sizeof(INT), &cx, offset);
+
+            MSFT_ReadLEDWords(&(*ppImpLib)->lcid,         sizeof(LCID),   &cx, DO_NOT_SEEK);
+            MSFT_ReadLEWords(&(*ppImpLib)->wVersionMajor, sizeof(WORD),   &cx, DO_NOT_SEEK);
+            MSFT_ReadLEWords(&(*ppImpLib)->wVersionMinor, sizeof(WORD),   &cx, DO_NOT_SEEK);
+            MSFT_ReadLEWords(& size,                      sizeof(UINT16), &cx, DO_NOT_SEEK);
 
             size >>= 2;
@@ -2656,5 +2795,5 @@
 	    }
 	}
-	
+
 	ppFuncDesc = &((*ppFuncDesc)->next);
 	if(pFunc->next == 0xffff) break;
@@ -2802,14 +2941,14 @@
 
     pHeader = pLib;
-    
+
     TRACE("header:\n");
     TRACE("\tmagic=0x%08lx, file blocks = %d\n", pHeader->SLTG_magic,
 	  pHeader->nrOfFileBlks );
-    if (memcmp(&pHeader->SLTG_magic, TLBMAGIC1, 4)) {
+    if (pHeader->SLTG_magic != SLTG_SIGNATURE) {
 	FIXME("Header type magic 0x%08lx not supported.\n",
 	      pHeader->SLTG_magic);
 	return NULL;
     }
-    
+
     /* There are pHeader->nrOfFileBlks - 2 TypeInfo records in this typelib */
     pTypeLibImpl->TypeInfoCount = pHeader->nrOfFileBlks - 2;
@@ -2844,9 +2983,5 @@
 	  pBlkEntry[order].next != 0;
 	  order = pBlkEntry[order].next - 1, i++) {
-#ifdef __WIN32OS2__
-        pBlk = (LPBYTE)pBlk + pBlkEntry[order].len;
-#else
-        pBlk += pBlkEntry[order].len;
-#endif
+       pBlk = (char*)pBlk + pBlkEntry[order].len;
     }
     pLibBlk = pBlk;
@@ -2867,5 +3002,5 @@
 
     ptr = (char*)pLibBlk + len;
-    
+
     for(i = 0; i < pTypeLibImpl->TypeInfoCount; i++) {
 	WORD w, extra;
@@ -2917,5 +3052,5 @@
        dust and we should be pointing at the beginning of the name
        table */
- 
+
     pNameTable = (char*)pLibBlk + len;
 
@@ -2930,5 +3065,5 @@
        break;
    }
-    
+
     pNameTable += 0x216;
 
@@ -2980,5 +3115,5 @@
       (*ppTypeInfoImpl)->TypeAttr.wTypeFlags =
 	(pTIHeader->typeflags1 >> 3) | (pTIHeader->typeflags2 << 5);
-      
+
       if((pTIHeader->typeflags1 & 7) != 2)
 	FIXME("typeflags1 = %02x\n", pTIHeader->typeflags1);
@@ -2994,9 +3129,9 @@
       switch(pTIHeader->typekind) {
       case TKIND_ENUM:
-	pTITail = SLTG_ProcessEnum(pBlk, *ppTypeInfoImpl, pNameTable); 
+	pTITail = SLTG_ProcessEnum(pBlk, *ppTypeInfoImpl, pNameTable);
 	break;
 
       case TKIND_RECORD:
-	pTITail = SLTG_ProcessRecord(pBlk, *ppTypeInfoImpl, pNameTable); 
+	pTITail = SLTG_ProcessRecord(pBlk, *ppTypeInfoImpl, pNameTable);
 	break;
 
@@ -3023,9 +3158,5 @@
       }
       ppTypeInfoImpl = &((*ppTypeInfoImpl)->next);
-#ifdef __WIN32OS2__
-      pBlk = (LPBYTE)pBlk + pBlkEntry[order].len;
-#else
-      pBlk += pBlkEntry[order].len;
-#endif
+      pBlk = (char*)pBlk + pBlkEntry[order].len;
     }
 
@@ -3051,5 +3182,5 @@
 
     *ppvObject=NULL;
-    if(IsEqualIID(riid, &IID_IUnknown) || 
+    if(IsEqualIID(riid, &IID_IUnknown) ||
        IsEqualIID(riid,&IID_ITypeLib)||
        IsEqualIID(riid,&IID_ITypeLib2))
@@ -3086,5 +3217,5 @@
 
     --(This->ref);
-    
+
     TRACE("(%p)->(%u)\n",This, This->ref);
 
@@ -3118,5 +3249,5 @@
           This->HelpStringDll = NULL;
       }
-    
+
       ITypeInfo_Release((ITypeInfo*) This->pTypeInfo);
       HeapFree(GetProcessHeap(),0,This);
@@ -3128,5 +3259,5 @@
 
 /* ITypeLib::GetTypeInfoCount
- * 
+ *
  * Returns the number of type descriptions in the type library
  */
@@ -3144,9 +3275,9 @@
 static HRESULT WINAPI ITypeLib2_fnGetTypeInfo(
     ITypeLib2 *iface,
-    UINT index, 
+    UINT index,
     ITypeInfo **ppTInfo)
 {
     int i;
-    
+
     ICOM_THIS( ITypeLibImpl, iface);
     ITypeInfoImpl *pTypeInfo = This->pTypeInfo;
@@ -3155,5 +3286,5 @@
 
     if (!ppTInfo) return E_INVALIDARG;
-    
+
     /* search element n in list */
     for(i=0; i < index; i++)
@@ -3165,8 +3296,8 @@
         return TYPE_E_ELEMENTNOTFOUND;
       }
-    }   
+    }
 
     *ppTInfo = (ITypeInfo *) pTypeInfo;
-    
+
     ITypeInfo_AddRef(*ppTInfo);
     TRACE("-- found (%p)\n",*ppTInfo);
@@ -3191,5 +3322,5 @@
 
     if(!pTKind) return E_INVALIDARG;
-    
+
     /* search element n in list */
     for(i=0; i < index; i++)
@@ -3238,6 +3369,6 @@
     }
 
-    TRACE("-- found (%p, %s)\n", 
-          pTypeInfo, 
+    TRACE("-- found (%p, %s)\n",
+          pTypeInfo,
           debugstr_w(pTypeInfo->Name));
 
@@ -3253,5 +3384,5 @@
  */
 static HRESULT WINAPI ITypeLib2_fnGetLibAttr(
-	ITypeLib2 *iface, 
+	ITypeLib2 *iface,
 	LPTLIBATTR *ppTLibAttr)
 {
@@ -3292,21 +3423,21 @@
     BSTR *pBstrName,
     BSTR *pBstrDocString,
-    DWORD *pdwHelpContext, 
+    DWORD *pdwHelpContext,
     BSTR *pBstrHelpFile)
 {
     ICOM_THIS( ITypeLibImpl, iface);
-    
+
     HRESULT result = E_INVALIDARG;
-    
+
     ITypeInfo *pTInfo;
 
-   
+
     TRACE("(%p) index %d Name(%p) DocString(%p) HelpContext(%p) HelpFile(%p)\n",
         This, index,
-        pBstrName, pBstrDocString, 
+        pBstrName, pBstrDocString,
         pdwHelpContext, pBstrHelpFile);
-   
+
     if(index<0)
-    { 
+    {
         /* documentation for the typelib */
         if(pBstrName)
@@ -3340,5 +3471,5 @@
         result = S_OK;
     }
-    else 
+    else
     {
         /* for a typeinfo */
@@ -3347,10 +3478,10 @@
         if(SUCCEEDED(result))
         {
-            result = ITypeInfo_GetDocumentation(pTInfo, 
-                                          MEMBERID_NIL,  
+            result = ITypeInfo_GetDocumentation(pTInfo,
+                                          MEMBERID_NIL,
                                           pBstrName,
-                                          pBstrDocString, 
+                                          pBstrDocString,
                                           pdwHelpContext, pBstrHelpFile);
-            
+
             ITypeInfo_Release(pTInfo);
         }
@@ -3398,5 +3529,5 @@
         for(pVInfo=pTInfo->varlist;pVInfo;pVInfo=pVInfo->next)
             if(!memcmp(szNameBuf,pVInfo->Name, nNameBufLen)) goto ITypeLib2_fnIsName_exit;
-       
+
     }
     *pfName=FALSE;
@@ -3405,5 +3536,5 @@
     TRACE("(%p)slow! search for %s: %s found!\n", This,
           debugstr_w(szNameBuf), *pfName?"NOT":"");
-    
+
     return S_OK;
 }
@@ -3428,5 +3559,5 @@
     TLBVarDesc *pVInfo;
     int i,j = 0;
-   
+
     UINT nNameBufLen = SysStringLen(szNameBuf);
 
@@ -3451,5 +3582,5 @@
 
     *pcFound=j;
-    
+
     return S_OK;
 }
@@ -3476,5 +3607,5 @@
 static HRESULT WINAPI ITypeLib2_fnGetCustData(
 	ITypeLib2 * iface,
-	REFGUID guid, 
+	REFGUID guid,
         VARIANT *pVarVal)
 {
@@ -3486,5 +3617,5 @@
       if( IsEqualIID(guid, &pCData->guid)) break;
     }
-    
+
     TRACE("(%p) guid %s %s found!x)\n", This, debugstr_guid(guid), pCData? "" : "NOT");
 
@@ -3505,5 +3636,5 @@
  */
 static HRESULT WINAPI ITypeLib2_fnGetLibStatistics(
-	ITypeLib2 * iface, 
+	ITypeLib2 * iface,
         ULONG *pcUniqueNames,
 	ULONG *pcchUniqueNames)
@@ -3526,5 +3657,5 @@
  */
 static HRESULT WINAPI ITypeLib2_fnGetDocumentation2(
-	ITypeLib2 * iface, 
+	ITypeLib2 * iface,
         INT index,
 	LCID lcid,
@@ -3559,24 +3690,24 @@
       /* for a typeinfo */
       result=ITypeLib2_GetTypeInfo(iface, index, &pTInfo);
-      
+
       if(SUCCEEDED(result))
-      { 
+      {
         ITypeInfo2 * pTInfo2;
-        result = ITypeInfo_QueryInterface(pTInfo, 
-                                          &IID_ITypeInfo2, 
+        result = ITypeInfo_QueryInterface(pTInfo,
+                                          &IID_ITypeInfo2,
                                           (LPVOID*) &pTInfo2);
 
         if(SUCCEEDED(result))
         {
-          result = ITypeInfo2_GetDocumentation2(pTInfo2, 
-                                           MEMBERID_NIL, 
+          result = ITypeInfo2_GetDocumentation2(pTInfo2,
+                                           MEMBERID_NIL,
                                            lcid,
-                                           pbstrHelpString, 
-                                           pdwHelpStringContext, 
+                                           pbstrHelpString,
+                                           pdwHelpStringContext,
                                            pbstrHelpStringDll);
-  
+
           ITypeInfo2_Release(pTInfo2);
         }
-            
+
         ITypeInfo_Release(pTInfo);
       }
@@ -3587,5 +3718,5 @@
 /* ITypeLib2::GetAllCustData
  *
- * Gets all custom data items for the library. 
+ * Gets all custom data items for the library.
  *
  */
@@ -3597,5 +3728,5 @@
     TLBCustData *pCData;
     int i;
-    TRACE("(%p) returning %d items\n", This, This->ctCustData); 
+    TRACE("(%p) returning %d items\n", This, This->ctCustData);
     pCustData->prgCustData = TLB_Alloc(This->ctCustData * sizeof(CUSTDATAITEM));
     if(pCustData->prgCustData ){
@@ -3661,5 +3792,5 @@
 
     *ppvObject=NULL;
-    if(IsEqualIID(riid, &IID_IUnknown) || 
+    if(IsEqualIID(riid, &IID_IUnknown) ||
             IsEqualIID(riid,&IID_ITypeInfo)||
             IsEqualIID(riid,&IID_ITypeInfo2))
@@ -3694,5 +3825,5 @@
 
     --(This->ref);
-    
+
     TRACE("(%p)->(%u)\n",This, This->ref);
 
@@ -3701,5 +3832,5 @@
       FIXME("destroy child objects\n");
 
-      TRACE("destroying ITypeInfo(%p)\n",This); 
+      TRACE("destroying ITypeInfo(%p)\n",This);
       if (This->Name)
       {
@@ -3707,5 +3838,5 @@
           This->Name = 0;
       }
-      
+
       if (This->DocString)
       {
@@ -3766,5 +3897,5 @@
     ICOM_THIS( ITypeInfoImpl, iface);
     int i;
-    TLBFuncDesc * pFDesc; 
+    TLBFuncDesc * pFDesc;
     TRACE("(%p) index %d\n", This, index);
     for(i=0, pFDesc=This->funclist; i!=index && pFDesc; i++, pFDesc=pFDesc->next)
@@ -3780,5 +3911,5 @@
 /* ITypeInfo::GetVarDesc
  *
- * Retrieves a VARDESC structure that describes the specified variable. 
+ * Retrieves a VARDESC structure that describes the specified variable.
  *
  */
@@ -3788,5 +3919,5 @@
     ICOM_THIS( ITypeInfoImpl, iface);
     int i;
-    TLBVarDesc * pVDesc; 
+    TLBVarDesc * pVDesc;
     TRACE("(%p) index %d\n", This, index);
     for(i=0, pVDesc=This->varlist; i!=index && pVDesc; i++, pVDesc=pVDesc->next)
@@ -3810,6 +3941,6 @@
 {
     ICOM_THIS( ITypeInfoImpl, iface);
-    TLBFuncDesc * pFDesc; 
-    TLBVarDesc * pVDesc; 
+    TLBFuncDesc * pFDesc;
+    TLBVarDesc * pVDesc;
     int i;
     TRACE("(%p) memid=0x%08lx Maxname=%d\n", This, memid, cMaxNames);
@@ -3890,5 +4021,5 @@
       */
       if( This->TypeAttr.typekind != TKIND_DISPATCH) return E_INVALIDARG;
-      
+
       if (This->TypeAttr.wTypeFlags & TYPEFLAG_FDISPATCHABLE &&
           This->TypeAttr.wTypeFlags & TYPEFLAG_FDUAL )
@@ -3909,19 +4040,19 @@
         pImpl = pImpl->next;
       }
-      
+
       if (!pImpl) return TYPE_E_ELEMENTNOTFOUND;
-      
+
       *pRefType = pImpl->hRef;
-      
+
       TRACE("-- 0x%08lx\n", pImpl->hRef );
     }
-    
+
     return S_OK;
-   
+
 }
 
 /* ITypeInfo::GetImplTypeFlags
- * 
- * Retrieves the IMPLTYPEFLAGS enumeration for one implemented interface 
+ *
+ * Retrieves the IMPLTYPEFLAGS enumeration for one implemented interface
  * or base interface in a type description.
  */
@@ -3953,6 +4084,6 @@
 {
     ICOM_THIS( ITypeInfoImpl, iface);
-    TLBFuncDesc * pFDesc; 
-    TLBVarDesc * pVDesc; 
+    TLBFuncDesc * pFDesc;
+    TLBVarDesc * pVDesc;
     HRESULT ret=S_OK;
 
@@ -3974,5 +4105,5 @@
             return ret;
         }
-    }   
+    }
     for(pVDesc=This->varlist; pVDesc; pVDesc=pVDesc->next) {
         if(!lstrcmpiW(*rgszNames, pVDesc->Name)) {
@@ -3981,10 +4112,10 @@
         }
     }
-    /* not found, see if this is and interface with an inheritance */       
-    if(This->TypeAttr.typekind==TKIND_INTERFACE && 
+    /* not found, see if this is and interface with an inheritance */
+    if(This->TypeAttr.typekind==TKIND_INTERFACE &&
             This->TypeAttr.cImplTypes ){
         /* recursive search */
         ITypeInfo *pTInfo;
-        ret=ITypeInfo_GetRefTypeInfo(iface, 
+        ret=ITypeInfo_GetRefTypeInfo(iface,
                 This->impltypelist->hRef, &pTInfo);
         if(SUCCEEDED(ret)){
@@ -4000,5 +4131,5 @@
 
 /* ITypeInfo::Invoke
- * 
+ *
  * Invokes a method, or accesses a property of an object, that implements the
  * interface described by the type description.
@@ -4018,6 +4149,6 @@
     case CC_STDCALL:
 
+#ifdef __WIN32OS2__
 	switch (nrargs) {
-#ifdef __WIN32OS2__
 	case 0: {
 		DWORD (* WINAPI xfunc)() = func;
@@ -4071,4 +4202,5 @@
 	}
 #else
+	switch (nrargs) {
 	case 0: {
 		DWORD (WINAPI *xfunc)() = func;
@@ -4110,5 +4242,5 @@
 		res = xfunc(args[0],args[1],args[2],args[3],args[4],args[5],args[6]);
 		break;
-        }
+	}
 	case 8: {
 		DWORD (WINAPI *xfunc)(DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD) = func;
@@ -4137,4 +4269,55 @@
 }
 
+extern int const _argsize(DWORD vt);
+
+/***********************************************************************
+ *		DispCallFunc (OLEAUT32.@)
+ */
+HRESULT WINAPI
+DispCallFunc(
+    void* pvInstance, ULONG oVft, CALLCONV cc, VARTYPE vtReturn, UINT cActuals,
+    VARTYPE* prgvt, VARIANTARG** prgpvarg, VARIANT* pvargResult
+) {
+    int i, argsize, argspos;
+    DWORD *args;
+    HRESULT hres;
+
+    FIXME("(%p, %ld, %d, %d, %d, %p, %p, %p)\n",
+	pvInstance, oVft, cc, vtReturn, cActuals, prgvt, prgpvarg, pvargResult
+    );
+    argsize = 0;
+    for (i=0;i<cActuals;i++) {
+        FIXME("arg %d: type %d\n",i,prgvt[i]);
+	dump_Variant(prgpvarg[i]);
+        argsize += _argsize(prgvt[i]);
+    }
+    args = (DWORD*)HeapAlloc(GetProcessHeap(),0,sizeof(DWORD)*argsize);
+    argspos = 0;
+    for (i=0;i<cActuals;i++) {
+	int arglen;
+        VARIANT *arg = prgpvarg[i];
+
+	arglen = _argsize(prgvt[i]);
+	if (V_VT(arg) == prgvt[i]) {
+	    memcpy(&args[argspos],&V_UNION(arg,lVal), arglen*sizeof(DWORD));
+	} else {
+	    if (prgvt[i] == VT_VARIANT) {
+		memcpy(&args[argspos],arg, arglen*sizeof(DWORD));
+	    } else {
+		ERR("Set arg %d to disparg type %d vs %d\n",i,
+			V_VT(arg),prgvt[i]
+		);
+	    }
+	}
+	argspos += arglen;
+    }
+
+    FIXME("Do not know how to handle pvargResult %p. Expect crash ...\n",pvargResult);
+
+    hres = _invoke((*(DWORD***)pvInstance)[oVft/4],cc,argsize/4,args);
+    HeapFree(GetProcessHeap(),0,args);
+    return hres;
+}
+
 static HRESULT WINAPI ITypeInfo_fnInvoke(
     ITypeInfo2 *iface,
@@ -4148,6 +4331,6 @@
 {
     ICOM_THIS( ITypeInfoImpl, iface);
-    TLBFuncDesc * pFDesc; 
-    TLBVarDesc * pVDesc; 
+    TLBFuncDesc * pFDesc;
+    TLBVarDesc * pVDesc;
     int i;
 
@@ -4164,33 +4347,61 @@
     if (pFDesc) {
 	dump_TLBFuncDescOne(pFDesc);
+	/* dump_FUNCDESC(&pFDesc->funcdesc);*/
 	switch (pFDesc->funcdesc.funckind) {
 	case FUNC_PUREVIRTUAL:
 	case FUNC_VIRTUAL: {
 	    DWORD res;
-	    DWORD *args = (DWORD*)HeapAlloc(GetProcessHeap(),0,sizeof(DWORD)*(pFDesc->funcdesc.cParams+1));
-	    DWORD *args2 = (DWORD*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(DWORD)*(pFDesc->funcdesc.cParams));
+	    int   numargs, numargs2, argspos, args2pos;
+	    DWORD *args , *args2;
+
+
+	    numargs = 1; numargs2 = 0;
+	    for (i=0;i<pFDesc->funcdesc.cParams;i++) {
+		if (i<pDispParams->cArgs)
+		    numargs += _argsize(pFDesc->funcdesc.lprgelemdescParam[i].tdesc.vt);
+		else {
+		    numargs	+= 1; /* sizeof(lpvoid) */
+		    numargs2	+= _argsize(pFDesc->funcdesc.lprgelemdescParam[i].tdesc.vt);
+		}
+	    }
+
+	    args = (DWORD*)HeapAlloc(GetProcessHeap(),0,sizeof(DWORD)*numargs);
+	    args2 = (DWORD*)HeapAlloc(GetProcessHeap(),0,sizeof(DWORD)*numargs2);
+
 	    args[0] = (DWORD)pIUnk;
-
+	    argspos = 1; args2pos = 0;
 	    for (i=0;i<pFDesc->funcdesc.cParams;i++) {
+		int arglen = _argsize(pFDesc->funcdesc.lprgelemdescParam[i].tdesc.vt);
 		if (i<pDispParams->cArgs) {
-		    TRACE("set %d to disparg type %d vs %d\n",i,
-			    V_VT(&pDispParams->rgvarg[pDispParams->cArgs-i-1]),
-			    pFDesc->funcdesc.lprgelemdescParam[i].tdesc.vt
-		    );
-		    args[i+1] = V_UNION(&pDispParams->rgvarg[pDispParams->cArgs-i-1],lVal);
+		    VARIANT *arg = &pDispParams->rgvarg[pDispParams->cArgs-i-1];
+		    TYPEDESC *tdesc = &pFDesc->funcdesc.lprgelemdescParam[i].tdesc;
+
+		    if (V_VT(arg) == tdesc->vt) {
+			memcpy(&args[argspos],&V_UNION(arg,lVal), arglen*sizeof(DWORD));
+		    } else {
+			if (tdesc->vt == VT_VARIANT) {
+			    memcpy(&args[argspos],arg, arglen*sizeof(DWORD));
+			} else {
+			    ERR("Set arg %d to disparg type %d vs %d\n",i,
+				    V_VT(arg),tdesc->vt
+			    );
+			}
+		    }
+		    argspos += arglen;
 		} else {
 		    TYPEDESC *tdesc = &(pFDesc->funcdesc.lprgelemdescParam[i].tdesc);
-		    TRACE("set %d to pointer for get (type is %d)\n",i,tdesc->vt);
+		    if (tdesc->vt != VT_PTR)
+		    	FIXME("set %d to pointer for get (type is %d)\n",i,tdesc->vt);
 		    /*FIXME: give pointers for the rest, so propertyget works*/
-		    args[i+1] = (DWORD)&args2[i];
-
-		    /* If pointer to variant, pass reference to variant
-		     * in result variant array.
-		     */
+		    args[argspos] = (DWORD)&args2[args2pos];
+
+		    /* If pointer to variant, pass reference it. */
 		    if ((tdesc->vt == VT_PTR) &&
 			(tdesc->u.lptdesc->vt == VT_VARIANT) &&
 			pVarResult
 		    )
-			args[i+1] = (DWORD)(pVarResult+(i-pDispParams->cArgs));
+			args[argspos]= (DWORD)pVarResult;
+		    argspos	+= 1;
+		    args2pos	+= arglen;
 		}
 	    }
@@ -4202,9 +4413,11 @@
 	    res = _invoke((*(DWORD***)pIUnk)[pFDesc->funcdesc.oVft/4],
 		    pFDesc->funcdesc.callconv,
-		    pFDesc->funcdesc.cParams+1,
+		    numargs,
 		    args
 	    );
 	    if (pVarResult && (dwFlags & (DISPATCH_PROPERTYGET))) {
+		args2pos = 0;
 		for (i=0;i<pFDesc->funcdesc.cParams-pDispParams->cArgs;i++) {
+		    int arglen = _argsize(pFDesc->funcdesc.lprgelemdescParam[i].tdesc.vt);
 		    TYPEDESC *tdesc = &(pFDesc->funcdesc.lprgelemdescParam[i+pDispParams->cArgs].tdesc);
 		    /* If we are a pointer to a variant, we are done already */
@@ -4212,10 +4425,10 @@
 			continue;
 
-		    VariantInit(&pVarResult[i]);
-		    V_UNION(pVarResult+i,intVal) = args2[i+pDispParams->cArgs];
+		    VariantInit(pVarResult);
+		    memcpy(&V_UNION(pVarResult,intVal),&args2[args2pos],arglen*sizeof(DWORD));
 
 		    if (tdesc->vt == VT_PTR)
 			tdesc = tdesc->u.lptdesc;
-		    V_VT(pVarResult+i) = tdesc->vt;
+		    V_VT(pVarResult) = tdesc->vt;
 
 		    /* HACK: VB5 likes this.
@@ -4225,7 +4438,8 @@
 		     */
 		    if ((tdesc->vt == VT_PTR) && (dwFlags & DISPATCH_METHOD))
-			V_VT(pVarResult+i) = VT_DISPATCH;
-		    TRACE("storing into variant: [%d]\n", i);
-		    dump_Variant(pVarResult+i);
+			V_VT(pVarResult) = VT_DISPATCH;
+		    TRACE("storing into variant:\n");
+		    dump_Variant(pVarResult);
+		    args2pos += arglen;
 		}
 	    }
@@ -4284,7 +4498,9 @@
 
 /* ITypeInfo::GetDocumentation
- * 
+ *
  * Retrieves the documentation string, the complete Help file name and path,
  * and the context ID for the Help topic for a specified type description.
+ *
+ * (Can be tested by the Visual Basic Editor in Word for instance.)
  */
 static HRESULT WINAPI ITypeInfo_fnGetDocumentation( ITypeInfo2 *iface,
@@ -4293,6 +4509,6 @@
 {
     ICOM_THIS( ITypeInfoImpl, iface);
-    TLBFuncDesc * pFDesc; 
-    TLBVarDesc * pVDesc; 
+    TLBFuncDesc * pFDesc;
+    TLBVarDesc * pVDesc;
     TRACE("(%p) memid %ld Name(%p) DocString(%p)"
           " HelpContext(%p) HelpFile(%p)\n",
@@ -4321,6 +4537,11 @@
     for(pVDesc=This->varlist; pVDesc; pVDesc=pVDesc->next)
         if(pVDesc->vardesc.memid==memid){
-	    FIXME("Not implemented\n");
-            return S_OK;
+	    if(pBstrName)
+	      *pBstrName = SysAllocString(pVDesc->Name);
+	    if(pBstrDocString)
+	      *pBstrDocString=SysAllocString(pVDesc->HelpString);
+	    if(pdwHelpContext)
+	      *pdwHelpContext=pVDesc->HelpContext;
+	    return S_OK;
         }
     }
@@ -4329,5 +4550,5 @@
 
 /*  ITypeInfo::GetDllEntry
- * 
+ *
  * Retrieves a description or specification of an entry point for a function
  * in a DLL.
@@ -4338,10 +4559,37 @@
 {
     ICOM_THIS( ITypeInfoImpl, iface);
-    FIXME("(%p) stub!\n", This);
+    TLBFuncDesc *pFDesc;
+
+    FIXME("(%p, memid %lx, %d, %p, %p, %p), partial stub!\n", This, memid, invKind, pBstrDllName, pBstrName, pwOrdinal);
+
+    for(pFDesc=This->funclist; pFDesc; pFDesc=pFDesc->next)
+        if(pFDesc->funcdesc.memid==memid){
+	    dump_TypeInfo(This);
+	    dump_TLBFuncDescOne(pFDesc);
+
+	    /* FIXME: This is wrong, but how do you find that out? */
+	    if (pBstrDllName) {
+		const WCHAR oleaut32W[] = {'O','L','E','A','U','T','3','2','.','D','L','L',0};
+		*pBstrDllName = SysAllocString(oleaut32W);
+	    }
+
+	    if (HIWORD(pFDesc->Entry) && (pFDesc->Entry != (void*)-1)) {
+		if (pBstrName)
+		    *pBstrName = SysAllocString(pFDesc->Entry);
+		if (pwOrdinal)
+		    *pwOrdinal = -1;
+		return S_OK;
+	    }
+	    if (pBstrName)
+		*pBstrName = NULL;
+	    if (pwOrdinal)
+		*pwOrdinal = (DWORD)pFDesc->Entry;
+	    return S_OK;
+        }
     return E_FAIL;
 }
 
 /* ITypeInfo::GetRefTypeInfo
- * 
+ *
  * If a type description references other type descriptions, it retrieves
  * the referenced type descriptions.
@@ -4356,14 +4604,14 @@
 
 
-    if (hRefType == -1 && 
+    if (hRefType == -1 &&
 	(((ITypeInfoImpl*) This)->TypeAttr.typekind   == TKIND_DISPATCH) &&
 	(((ITypeInfoImpl*) This)->TypeAttr.wTypeFlags &  TYPEFLAG_FDUAL))
     {
-	  /* when we meet a DUAL dispinterface, we must create the interface 
+	  /* when we meet a DUAL dispinterface, we must create the interface
 	  * version of it.
 	  */
 	  ITypeInfoImpl* pTypeInfoImpl = (ITypeInfoImpl*) ITypeInfo_Constructor();
 
-		
+
 	  /* the interface version contains the same information as the dispinterface
 	   * copy the contents of the structs.
@@ -4371,8 +4619,8 @@
 	  *pTypeInfoImpl = *This;
 	  pTypeInfoImpl->ref = 1;
-		
+
 	  /* change the type to interface */
 	  pTypeInfoImpl->TypeAttr.typekind = TKIND_INTERFACE;
-	  
+
 	  *ppTInfo = (ITypeInfo*) pTypeInfoImpl;
 
@@ -4422,6 +4670,6 @@
 	    if(SUCCEEDED(result)) {
 	        if(pRefType->index == TLB_REF_USE_GUID)
-		    result = ITypeLib2_GetTypeInfoOfGuid(pTLib, 
-							 &pRefType->guid, 
+		    result = ITypeLib2_GetTypeInfoOfGuid(pTLib,
+							 &pRefType->guid,
 							 ppTInfo);
 		else
@@ -4440,5 +4688,5 @@
 
 /* ITypeInfo::AddressOfMember
- * 
+ *
  * Retrieves the addresses of static functions or variables, such as those
  * defined in a DLL.
@@ -4453,10 +4701,10 @@
 
 /* ITypeInfo::CreateInstance
- * 
- * Creates a new instance of a type that describes a component object class 
+ *
+ * Creates a new instance of a type that describes a component object class
  * (coclass).
  */
-static HRESULT WINAPI ITypeInfo_fnCreateInstance( ITypeInfo2 *iface, 
-        IUnknown *pUnk, REFIID riid, VOID  **ppvObj) 
+static HRESULT WINAPI ITypeInfo_fnCreateInstance( ITypeInfo2 *iface,
+        IUnknown *pUnk, REFIID riid, VOID  **ppvObj)
 {
     ICOM_THIS( ITypeInfoImpl, iface);
@@ -4478,5 +4726,5 @@
 
 /* ITypeInfo::GetContainingTypeLib
- * 
+ *
  * Retrieves the containing type library and the index of the type description
  * within that type library.
@@ -4551,5 +4799,5 @@
  * Returns the type flags without any allocations. This returns a DWORD type
  * flag, which expands the type flags without growing the TYPEATTR (type
- * attribute). 
+ * attribute).
  *
  */
@@ -4576,5 +4824,5 @@
     HRESULT result;
     /* FIXME: should check for invKind??? */
-    for(i=0, pFuncInfo=This->funclist;pFuncInfo && 
+    for(i=0, pFuncInfo=This->funclist;pFuncInfo &&
             memid != pFuncInfo->funcdesc.memid; i++, pFuncInfo=pFuncInfo->next);
     if(pFuncInfo){
@@ -4593,5 +4841,5 @@
  *
  * Binds to a specific member based on a known DISPID, where the member name
- * is not known (for example, when binding to a default member). 
+ * is not known (for example, when binding to a default member).
  *
  */
@@ -4603,5 +4851,5 @@
     int i;
     HRESULT result;
-    for(i=0, pVarInfo=This->varlist; pVarInfo && 
+    for(i=0, pVarInfo=This->varlist; pVarInfo &&
             memid != pVarInfo->vardesc.memid; i++, pVarInfo=pVarInfo->next)
         ;
@@ -4656,5 +4904,5 @@
     ICOM_THIS( ITypeInfoImpl, iface);
     TLBCustData *pCData=NULL;
-    TLBFuncDesc * pFDesc; 
+    TLBFuncDesc * pFDesc;
     int i;
     for(i=0, pFDesc=This->funclist; i!=index && pFDesc; i++,
@@ -4685,8 +4933,8 @@
 	REFGUID guid,
 	VARIANT *pVarVal)
-{   
+{
     ICOM_THIS( ITypeInfoImpl, iface);
     TLBCustData *pCData=NULL;
-    TLBFuncDesc * pFDesc; 
+    TLBFuncDesc * pFDesc;
     int i;
 
@@ -4694,5 +4942,5 @@
 
     if(pFDesc && indexParam >=0 && indexParam<pFDesc->funcdesc.cParams)
-        for(pCData=pFDesc->pParamDesc[indexParam].pCustData; pCData; 
+        for(pCData=pFDesc->pParamDesc[indexParam].pCustData; pCData;
                 pCData = pCData->next)
             if( IsEqualIID(guid, &pCData->guid)) break;
@@ -4718,8 +4966,8 @@
 	REFGUID guid,
 	VARIANT *pVarVal)
-{   
+{
     ICOM_THIS( ITypeInfoImpl, iface);
     TLBCustData *pCData=NULL;
-    TLBVarDesc * pVDesc; 
+    TLBVarDesc * pVDesc;
     int i;
 
@@ -4754,8 +5002,8 @@
 	REFGUID guid,
 	VARIANT *pVarVal)
-{   
+{
     ICOM_THIS( ITypeInfoImpl, iface);
     TLBCustData *pCData=NULL;
-    TLBImplType * pRDesc; 
+    TLBImplType * pRDesc;
     int i;
 
@@ -4769,5 +5017,5 @@
       }
     }
-    
+
     TRACE("(%p) guid %s %s found!x)\n", This, debugstr_guid(guid), pCData? "" : "NOT");
 
@@ -4782,5 +5030,5 @@
 
 /* ITypeInfo2::GetDocumentation2
- * 
+ *
  * Retrieves the documentation string, the complete Help file name and path,
  * the localization context to use, and the context ID for the library Help
@@ -4797,6 +5045,6 @@
 {
     ICOM_THIS( ITypeInfoImpl, iface);
-    TLBFuncDesc * pFDesc; 
-    TLBVarDesc * pVDesc; 
+    TLBFuncDesc * pFDesc;
+    TLBVarDesc * pVDesc;
     TRACE("(%p) memid %ld lcid(0x%lx)  HelpString(%p) "
           "HelpStringContext(%p) HelpStringDll(%p)\n",
@@ -4845,5 +5093,5 @@
 /* ITypeInfo2::GetAllCustData
  *
- * Gets all custom data items for the Type info. 
+ * Gets all custom data items for the Type info.
  *
  */
@@ -4856,5 +5104,5 @@
     int i;
 
-    TRACE("(%p) returning %d items\n", This, This->ctCustData); 
+    TRACE("(%p) returning %d items\n", This, This->ctCustData);
 
     pCustData->prgCustData = TLB_Alloc(This->ctCustData * sizeof(CUSTDATAITEM));
@@ -4884,7 +5132,7 @@
     ICOM_THIS( ITypeInfoImpl, iface);
     TLBCustData *pCData;
-    TLBFuncDesc * pFDesc; 
+    TLBFuncDesc * pFDesc;
     int i;
-    TRACE("(%p) index %d\n", This, index); 
+    TRACE("(%p) index %d\n", This, index);
     for(i=0, pFDesc=This->funclist; i!=index && pFDesc; i++,
             pFDesc=pFDesc->next)
@@ -4920,12 +5168,12 @@
     ICOM_THIS( ITypeInfoImpl, iface);
     TLBCustData *pCData=NULL;
-    TLBFuncDesc * pFDesc; 
+    TLBFuncDesc * pFDesc;
     int i;
-    TRACE("(%p) index %d\n", This, indexFunc); 
+    TRACE("(%p) index %d\n", This, indexFunc);
     for(i=0, pFDesc=This->funclist; i!=indexFunc && pFDesc; i++,
             pFDesc=pFDesc->next)
         ;
     if(pFDesc && indexParam >=0 && indexParam<pFDesc->funcdesc.cParams){
-        pCustData->prgCustData = 
+        pCustData->prgCustData =
             TLB_Alloc(pFDesc->pParamDesc[indexParam].ctCustData *
                     sizeof(CUSTDATAITEM));
@@ -4957,7 +5205,7 @@
     ICOM_THIS( ITypeInfoImpl, iface);
     TLBCustData *pCData;
-    TLBVarDesc * pVDesc; 
+    TLBVarDesc * pVDesc;
     int i;
-    TRACE("(%p) index %d\n", This, index); 
+    TRACE("(%p) index %d\n", This, index);
     for(i=0, pVDesc=This->varlist; i!=index && pVDesc; i++,
             pVDesc=pVDesc->next)
@@ -4995,7 +5243,7 @@
     ICOM_THIS( ITypeInfoImpl, iface);
     TLBCustData *pCData;
-    TLBImplType * pRDesc; 
+    TLBImplType * pRDesc;
     int i;
-    TRACE("(%p) index %d\n", This, index); 
+    TRACE("(%p) index %d\n", This, index);
     for(i=0, pRDesc=This->impltypelist; i!=index && pRDesc; i++,
             pRDesc=pRDesc->next)
@@ -5021,5 +5269,5 @@
 }
 
-static ICOM_VTABLE(ITypeInfo2) tinfvt = 
+static ICOM_VTABLE(ITypeInfo2) tinfvt =
 {
     ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
Index: trunk/src/oleaut32/typelib.h
===================================================================
--- trunk/src/oleaut32/typelib.h	(revision 9394)
+++ trunk/src/oleaut32/typelib.h	(revision 9400)
@@ -25,6 +25,4 @@
 #include "wine/windef16.h"
 
-#define TLBMAGIC2 "MSFT"
-#define TLBMAGIC1 "SLTG"
 #define HELPDLLFLAG (0x0100)
 #define DO_NOT_SEEK (-1)
@@ -138,6 +136,11 @@
         INT     helpcontext;    /* */
         INT     oCustData;          /* offset in customer data table */
+#ifdef WORDS_BIGENDIAN
+        INT16   cbSizeVft;      /* virtual table size, not including inherits */
+        INT16   cImplTypes;     /* nr of implemented interfaces */
+#else
         INT16   cImplTypes;     /* nr of implemented interfaces */
         INT16   cbSizeVft;      /* virtual table size, not including inherits */
+#endif
 /*050*/ INT     size;           /* size in bytes, at least for structures */
         /* FIXME: name of this field */
@@ -165,6 +168,11 @@
     INT   DataType;     /* data type of the memeber, eg return of function */
     INT   Flags;        /* something to do with attribute flags (LOWORD) */
+#ifdef WORDS_BIGENDIAN
+    INT16 res3;         /* some offset into dunno what */
+    INT16 VtableOffset; /* offset in vtable */
+#else
     INT16 VtableOffset; /* offset in vtable */
     INT16 res3;         /* some offset into dunno what */
+#endif
     INT   FKCCIC;       /* bit string with the following  */
                         /* meaning (bit 0 is the msb): */
@@ -175,6 +183,11 @@
                         /* Invokation kind (bits 9-12 ) */
                         /* function kind (eg virtual), bits 13-15  */
+#ifdef WORDS_BIGENDIAN
+    INT16 nroargs;      /* nr of optional arguments */
+    INT16 nrargs;       /* number of arguments (including optional ????) */
+#else
     INT16 nrargs;       /* number of arguments (including optional ????) */
     INT16 nroargs;      /* nr of optional arguments */
+#endif
     /* optional attribute fields, the number of them is variable */
     INT   OptAttr[1];
@@ -209,6 +222,11 @@
     INT   DataType;     /* data type of the variable */
     INT   Flags;        /* VarFlags (LOWORD) */
+#ifdef WORDS_BIGENDIAN
+    INT16 res3;         /* some offset into dunno what */
+    INT16 VarKind;      /* VarKind */
+#else
     INT16 VarKind;      /* VarKind */
     INT16 res3;         /* some offset into dunno what */
+#endif
     INT   OffsValue;    /* value of the variable or the offset  */
                         /* in the data structure */
@@ -558,8 +576,16 @@
 extern DWORD _invoke(LPVOID func,CALLCONV callconv, int nrargs, DWORD *args);
 
+#ifdef __WIN32OS2__
+#ifdef DEBUG
+extern void dump_Variant(VARIANT * pvar);
+#else
+#define  dump_Variant(a)
+#endif
+#else
+extern void dump_Variant(VARIANT * pvar);
+#endif
+
 #include "poppack.h"
 
 /*---------------------------END--------------------------------------------*/
 #endif
-
-
Index: trunk/src/oleaut32/variant.c
===================================================================
--- trunk/src/oleaut32/variant.c	(revision 9394)
+++ trunk/src/oleaut32/variant.c	(revision 9400)
@@ -36,5 +36,5 @@
 
 #include "config.h"
- 
+
 #include <string.h>
 #include <stdlib.h>
@@ -53,4 +53,5 @@
 #include "winerror.h"
 #include "parsedt.h"
+#include "typelib.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(ole);
@@ -100,19 +101,104 @@
  * 400 then it is a leap year.
  */
-/* 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)))
- * So according to this there is 365.2515 days in one year.
- * One + every four years: 1/4 -> 365.25
- * One - every 100 years: 1/100 -> 365.01
- * One + every 400 years: 1/400 -> 365.0025
- */
-/* static const double DAYS_IN_ONE_YEAR = 365.2515;
+
+/*
+ * Use 365 days/year and a manual calculation for leap year days
+ * to keep arithmetic simple
+ */
+static const double DAYS_IN_ONE_YEAR = 365.0;
+
+/*
+ * Token definitions for Varient Formatting
+ * Worked out by experimentation on a w2k machine. Doesnt appear to be
+ *   documented anywhere obviously so keeping definitions internally
  *
- *  ^^  Might this be the key to an easy way to factor large prime numbers?
- *  Let's try using arithmetic.  <lawson_whitney@juno.com> 7 Mar 2000
- */
-static const double DAYS_IN_ONE_YEAR = 365.2425;
-
+ */
+/* Pre defined tokens */
+#define TOK_COPY 0x00
+#define TOK_END  0x02
+#define LARGEST_TOKENID 6
+
+/* Mapping of token name to id put into the tokenized form
+   Note testing on W2K shows aaaa and oooo are not parsed??!! */
+#define TOK_COLON  0x03
+#define TOK_SLASH  0x04
+#define TOK_c      0x05
+#define TOK_d      0x08
+#define TOK_dd     0x09
+#define TOK_ddd    0x0a
+#define TOK_dddd   0x0b
+#define TOK_ddddd  0x0c
+#define TOK_dddddd 0x0d
+#define TOK_w      0x0f
+#define TOK_ww     0x10
+#define TOK_m      0x11
+#define TOK_mm     0x12
+#define TOK_mmm    0x13
+#define TOK_mmmm   0x14
+#define TOK_q      0x06
+#define TOK_y      0x15
+#define TOK_yy     0x16
+#define TOK_yyyy   0x18
+#define TOK_h      0x1e
+#define TOK_Hh     0x1f
+#define TOK_N      0x1a
+#define TOK_Nn     0x1b
+#define TOK_S      0x1c
+#define TOK_Ss     0x1d
+#define TOK_ttttt  0x07
+#define TOK_AMsPM  0x2f
+#define TOK_amspm  0x32
+#define TOK_AsP    0x30
+#define TOK_asp    0x33
+#define TOK_AMPM   0x2e
+
+typedef struct tagFORMATTOKEN {
+    char  *str;
+    BYTE   tokenSize;
+    BYTE   tokenId;
+    int    varTypeRequired;
+} FORMATTOKEN;
+
+typedef struct tagFORMATHDR {
+    BYTE   len;
+    BYTE   hex3;
+    BYTE   hex6;
+    BYTE   reserved[8];
+} FORMATHDR;
+
+FORMATTOKEN formatTokens[] = {           /* FIXME: Only date formats so far */
+    {":"     ,   1,  TOK_COLON  , 0},
+    {"/"     ,   1,  TOK_SLASH  , 0},
+    {"c"     ,   1,  TOK_c      , VT_DATE},
+    {"dddddd",   6,  TOK_dddddd , VT_DATE},
+    {"ddddd" ,   5,  TOK_ddddd  , VT_DATE},
+    {"dddd"  ,   4,  TOK_dddd   , VT_DATE},
+    {"ddd"   ,   3,  TOK_ddd    , VT_DATE},
+    {"dd"    ,   2,  TOK_dd     , VT_DATE},
+    {"d"     ,   1,  TOK_d      , VT_DATE},
+    {"ww"    ,   2,  TOK_ww     , VT_DATE},
+    {"w"     ,   1,  TOK_w      , VT_DATE},
+    {"mmmm"  ,   4,  TOK_mmmm   , VT_DATE},
+    {"mmm"   ,   3,  TOK_mmm    , VT_DATE},
+    {"mm"    ,   2,  TOK_mm     , VT_DATE},
+    {"m"     ,   1,  TOK_m      , VT_DATE},
+    {"q"     ,   1,  TOK_q      , VT_DATE},
+    {"yyyy"  ,   4,  TOK_yyyy   , VT_DATE},
+    {"yy"    ,   2,  TOK_yy     , VT_DATE},
+    {"y"     ,   1,  TOK_y      , VT_DATE},
+    {"h"     ,   1,  TOK_h      , VT_DATE},
+    {"Hh"    ,   2,  TOK_Hh     , VT_DATE},
+    {"Nn"    ,   2,  TOK_Nn     , VT_DATE},
+    {"N"     ,   1,  TOK_N      , VT_DATE},
+    {"S"     ,   1,  TOK_S      , VT_DATE},
+    {"Ss"    ,   2,  TOK_Ss     , VT_DATE},
+    {"ttttt" ,   5,  TOK_ttttt  , VT_DATE},
+    {"AM/PM" ,   5,  TOK_AMsPM  , VT_DATE},
+    {"am/pm" ,   5,  TOK_amspm  , VT_DATE},
+    {"A/P"   ,   3,  TOK_AsP    , VT_DATE},
+    {"a/p"   ,   3,  TOK_asp    , VT_DATE},
+    {"AMPM"  ,   4,  TOK_AMPM   , VT_DATE},
+    {0x00    ,   0,  0          , VT_NULL}
+};
 
 /******************************************************************************
@@ -248,5 +334,6 @@
     int leapYear = 0;
 
-    if( (pTm->tm_year - 1900) < 0 ) return FALSE;
+    /* Hmmm... An uninitialized Date in VB is December 30 1899 so
+       Start at 0. This is the way DATE is defined. */
 
     /* Start at 1. This is the way DATE is defined.
@@ -257,73 +344,80 @@
     *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;
+    if( (pTm->tm_year - 1900) >= 0 ) {
+
+        /* 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.
+         * Copied + reversed functionality into TmToDate
+         */
+        *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. (remember tm_mon is 0..11)
+         */
+        switch( pTm->tm_mon )
+        {
+        case 1:
+            *pDateOut += 31;
+            break;
+        case 2:
+            *pDateOut += ( 59 + leapYear );
+            break;
+        case 3:
+            *pDateOut += ( 90 + leapYear );
+            break;
+        case 4:
+            *pDateOut += ( 120 + leapYear );
+            break;
+        case 5:
+            *pDateOut += ( 151 + leapYear );
+            break;
+        case 6:
+            *pDateOut += ( 181 + leapYear );
+            break;
+        case 7:
+            *pDateOut += ( 212 + leapYear );
+            break;
+        case 8:
+            *pDateOut += ( 243 + leapYear );
+            break;
+        case 9:
+            *pDateOut += ( 273 + leapYear );
+            break;
+        case 10:
+            *pDateOut += ( 304 + leapYear );
+            break;
+        case 11:
+            *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.
+         */
+    } else {
+        *pDateOut = 0;
     }
-    /* 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;
@@ -346,13 +440,8 @@
  * Returns TRUE if successful.
  */
-static BOOL DateToTm( DATE dateIn, DWORD dwFlags, struct tm* pTm )
+BOOL DateToTm( DATE dateIn, DWORD dwFlags, struct tm* pTm )
 {
     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));
@@ -365,99 +454,125 @@
      * This simplifies the processing of the DATE value.
      */
+    decimalPart = fmod( dateIn, 1.0 ); /* Do this before the -1, otherwise 0.xx goes negative */
     dateIn -= 1.0;
-
     wholePart = (double) floor( dateIn );
-    decimalPart = fmod( dateIn, wholePart );
 
     if( !(dwFlags & VAR_TIMEVALUEONLY) )
     {
-        int nDay = 0;
+        unsigned 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;
+
+        /* Hard code dates smaller than January 1, 1900. */
+        if( dateIn < 2.0 ) {
+            pTm->tm_year = 1899;
+            pTm->tm_mon  = 11; /* December as tm_mon is 0..11 */
+            if( dateIn < 1.0 ) {
+                pTm->tm_mday  = 30;
+                dateIn = dateIn * -1.0; /* Ensure +ve for time calculation */
+                decimalPart = decimalPart * -1.0; /* Ensure +ve for time calculation */
+            } else {
+                pTm->tm_mday  = 31;
+            }
+
+        } else {
+
+            /* 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 = (((unsigned int) wholePart) - ((pTm->tm_year-1900) * DAYS_IN_ONE_YEAR ));
+
+            /* Remove 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.
+             * Copied + reversed functionality from TmToDate
+             */
+            nDay -= ( (pTm->tm_year - 1) / 4 ) - ( 1900 / 4 );
+            nDay += ( (pTm->tm_year - 1) / 100 ) - ( 1900 / 100 );
+            nDay -= ( (pTm->tm_year - 1) / 400 ) - ( 1900 / 400 );
+
+            /* 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;
+            }
         }
     }
@@ -466,8 +581,12 @@
         /* find the number of seconds in this day.
          * fractional part times, hours, minutes, seconds.
+         * Note: 0.1 is hack to ensure figures come out in whole numbers
+         *   due to floating point inaccuracies
          */
         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 );
+        /* Note: 0.1 is hack to ensure seconds come out in whole numbers
+             due to floating point inaccuracies */
+        pTm->tm_sec = (int) (( ( ( decimalPart * 24 * 60 ) - ( pTm->tm_hour * 60 ) - pTm->tm_min ) * 60 ) + 0.1);
     }
     return TRUE;
@@ -521,10 +640,12 @@
         break;
     case( VT_BSTR ):
+    case( VT_DISPATCH ):
+    case( VT_UNKNOWN ):
         size = sizeof(void*);
         break;
     case( VT_CY ):
-    case( VT_DISPATCH ):
-    case( VT_UNKNOWN ):
-    case( VT_DECIMAL ):
+	size = sizeof(CY);
+	break;
+    case( VT_DECIMAL ):		/* hmm, tricky, DECIMAL is only VT_BYREF */
     default:
         FIXME("Add size information for type vt=%d\n", V_VT(parg) & VT_TYPEMASK );
@@ -536,5 +657,5 @@
 /******************************************************************************
  *	   StringDupAtoBstr		[INTERNAL]
- * 
+ *
  */
 static BSTR StringDupAtoBstr( char* strIn )
@@ -563,5 +684,5 @@
    nSign = (d >= 0.0) ? 1 : -1;
     d = fabs( d );
-    
+
 	/* Remove the decimals.
 	 */
@@ -630,5 +751,5 @@
 		str[0] = '\0';
 		strToken = strtok( pNewString, strOfCharToRemove );
-		while( strToken != NULL ) { 
+		while( strToken != NULL ) {
 			strcat( str, strToken );
 			strToken = strtok( NULL, strOfCharToRemove );
@@ -671,5 +792,5 @@
 	int nTokens = 0;
 	LPSTR pChar = NULL;
-	
+
 	/* Check if we have a valid argument
 	 */
@@ -684,7 +805,7 @@
 		 */
 		strToken = strtok( strRealString, " " );
-		while( strToken != NULL ) { 
-			nTokens++;		
-			strToken = strtok( NULL, " " );	
+		while( strToken != NULL ) {
+			nTokens++;
+			strToken = strtok( NULL, " " );
 		}
 
@@ -778,5 +899,5 @@
 		case '7':
 		case '8':
-		case '9': 
+		case '9':
 			if( bFirstDigitsProcessed == FALSE )
 			{
@@ -824,5 +945,5 @@
 		/* If DecimalPoint...
 		 */
-		case '.': 
+		case '.':
 			if( bDecimalPointProcessed ||
 				bSecondDigitsProcessed ||
@@ -894,5 +1015,5 @@
 	vtFrom = V_VT(ps) & VT_TYPEMASK;
 
-	
+
 	/* Note: Since "long" and "int" values both have 4 bytes and are
 	 * both signed integers "int" will be treated as "long" in the
@@ -901,5 +1022,5 @@
 	 */
 
-	/* Trivial Case: If the coercion is from two types that are 
+	/* Trivial Case: If the coercion is from two types that are
 	 * identical then we can blindly copy from one argument to another.*/
 	if ((vt==vtFrom))
@@ -1247,5 +1368,5 @@
 		}
 		break;
-		
+
 	case( VT_R4 ):
 		switch( vtFrom )
@@ -1610,5 +1731,5 @@
 		break;
 	}
-	
+
 	return res;
 }
@@ -1656,5 +1777,5 @@
 			res = DISP_E_BADVARTYPE;
 		}
-			
+
     }
     else
@@ -1662,5 +1783,5 @@
         res = ValidateVtRange( vt );
     }
-		
+
 	return res;
 }
@@ -1689,5 +1810,5 @@
 			res = DISP_E_BADVARTYPE;
 		}
-			
+
     }
     else
@@ -1695,5 +1816,5 @@
         res = ValidateVtRange( vt );
     }
-		
+
 	return res;
 }
@@ -1770,5 +1891,5 @@
       }
     }
-	
+
     /*
      * Empty all the fields and mark the type as empty.
@@ -1800,5 +1921,5 @@
   {
     res = VariantClear( pvargDest );
-		
+
     if( res == S_OK )
     {
@@ -1854,7 +1975,7 @@
 	  }
 	}
-	
+
 	V_VT(pvargDest) = V_VT(pvargSrc);
-      }      
+      }
     }
   }
@@ -1880,5 +2001,5 @@
   if( res != S_OK )
     return res;
-  
+
   if( V_VT(pvargSrc) & VT_BYREF )
   {
@@ -1931,5 +2052,5 @@
 		 * If the inner Variant itself contains an
 		 * other inner variant the E_INVALIDARG error is
-		 * returned. 
+		 * returned.
 		 */
 		if( pvargSrc->n1.n2.wReserved1 & PROCESSING_INNER_VARIANT )
@@ -1948,5 +2069,5 @@
 		   */
 		  (V_UNION(pvargSrc,pvarVal))->n1.n2.wReserved1 |= PROCESSING_INNER_VARIANT;
-		  
+
 		  /* Dereference the inner variant.
 		   */
@@ -2011,6 +2132,8 @@
 	VARIANTARG varg;
 	VariantInit( &varg );
-	
+
 	TRACE("(%p, %p, %ld, %u, %u) vt=%d\n", pvargDest, pvargSrc, lcid, wFlags, vt, V_VT(pvargSrc));
+    TRACE("Src Var:\n");
+    dump_Variant(pvargSrc);
 
 	/* validate our source argument.
@@ -2056,5 +2179,5 @@
 				VariantClear( &Variant );
 			}
-	
+
 		}
 		else
@@ -2068,5 +2191,5 @@
 	 */
 	VariantClear( &varg );
-	
+
 	/* set the type of the destination
 	 */
@@ -2074,4 +2197,7 @@
 		V_VT(pvargDest) = vt;
 
+    TRACE("Dest Var:\n");
+    dump_Variant(pvargDest);
+
 	return res;
 }
@@ -2095,5 +2221,5 @@
 
 	*pbOut = (BYTE) sIn;
-	
+
 	return S_OK;
 }
@@ -2114,5 +2240,5 @@
 
 	*pbOut = (BYTE) lIn;
-	
+
 	return S_OK;
 }
@@ -2135,5 +2261,5 @@
 
 	*pbOut = (BYTE) fltIn;
-	
+
 	return S_OK;
 }
@@ -2264,5 +2390,5 @@
 	 */
 	dValue = atof( pNewString );
-	
+
 	/* We don't need the string anymore so free it.
 	 */
@@ -2288,7 +2414,7 @@
 HRESULT WINAPI VarUI1FromCy(CY cyIn, BYTE* pbOut) {
    double t = round((((double)cyIn.s.Hi * 4294967296.0) + (double)cyIn.s.Lo) / 10000);
-   
+
    if (t > UI1_MAX || t < UI1_MIN) return DISP_E_OVERFLOW;
-   
+
    *pbOut = (BYTE)t;
    return S_OK;
@@ -2303,5 +2429,5 @@
 
 	*psOut = (short) bIn;
-	
+
 	return S_OK;
 }
@@ -2322,5 +2448,5 @@
 
 	*psOut = (short) lIn;
-	
+
 	return S_OK;
 }
@@ -2470,5 +2596,5 @@
 	 */
 	dValue = atof( pNewString );
-	
+
 	/* We don't need the string anymore so free it.
 	 */
@@ -2494,7 +2620,7 @@
 HRESULT WINAPI VarI2FromCy(CY cyIn, short* psOut) {
    double t = round((((double)cyIn.s.Hi * 4294967296.0) + (double)cyIn.s.Lo) / 10000);
-   
+
    if (t > I2_MAX || t < I2_MIN) return DISP_E_OVERFLOW;
-   
+
    *psOut = (SHORT)t;
    return S_OK;
@@ -2663,5 +2789,5 @@
 	 */
 	dValue = atof( pNewString );
-	
+
 	/* We don't need the string anymore so free it.
 	 */
@@ -2687,7 +2813,7 @@
 HRESULT WINAPI VarI4FromCy(CY cyIn, LONG* plOut) {
    double t = round((((double)cyIn.s.Hi * 4294967296.0) + (double)cyIn.s.Lo) / 10000);
-   
+
    if (t > I4_MAX || t < I4_MIN) return DISP_E_OVERFLOW;
-   
+
    *plOut = (LONG)t;
    return S_OK;
@@ -2838,5 +2964,5 @@
 	 */
 	dValue = atof( pNewString );
-	
+
 	/* We don't need the string anymore so free it.
 	 */
@@ -2861,5 +2987,5 @@
 HRESULT WINAPI VarR4FromCy(CY cyIn, FLOAT* pfltOut) {
    *pfltOut = (FLOAT)((((double)cyIn.s.Hi * 4294967296.0) + (double)cyIn.s.Lo) / 10000);
-   
+
    return S_OK;
 }
@@ -2981,9 +3107,9 @@
 	LPSTR pNewString = NULL;
 
-	TRACE("( %p, %ld, %ld, %p ), stub\n", strIn, lcid, dwFlags, pdblOut );
+	pNewString = HEAP_strdupWtoA( GetProcessHeap(), 0, strIn );
+	TRACE("( %s, %ld, %ld, %p ), stub\n", pNewString, lcid, dwFlags, pdblOut );
 
 	/* Check if we have a valid argument
 	 */
-	pNewString = HEAP_strdupWtoA( GetProcessHeap(), 0, strIn );
 	RemoveCharacterFromString( pNewString, "," );
 	if( IsValidRealString( pNewString ) == FALSE )
@@ -2995,5 +3121,5 @@
 	 */
 	dValue = atof( pNewString );
-	
+
 	/* We don't need the string anymore so free it.
 	 */
@@ -3011,5 +3137,5 @@
 HRESULT WINAPI VarR8FromCy(CY cyIn, double* pdblOut) {
    *pdblOut = (double)((((double)cyIn.s.Hi * 4294967296.0) + (double)cyIn.s.Lo) / 10000);
-   
+   TRACE("%lu %ld -> %f\n", cyIn.s.Hi, cyIn.s.Lo, *pdblOut);
    return S_OK;
 }
@@ -3100,7 +3226,7 @@
  *
  * The formats for the date part are has follows:
- * mm/[dd/][yy]yy 
+ * mm/[dd/][yy]yy
  * [dd/]mm/[yy]yy
- * [yy]yy/mm/dd 
+ * [yy]yy/mm/dd
  * January dd[,] [yy]yy
  * dd January [yy]yy
@@ -3109,5 +3235,5 @@
  *
  * The formats for the date and time string are has follows.
- * date[whitespace][time] 
+ * date[whitespace][time]
  * [time][whitespace]date
  *
@@ -3135,6 +3261,5 @@
         ret = DISP_E_TYPEMISMATCH;
     }
-
-
+    TRACE("Return value %f\n", *pdateOut);
 	return ret;
 }
@@ -3218,5 +3343,5 @@
 
 	*pbstrOut =  StringDupAtoBstr( pBuffer );
-	
+
 	return S_OK;
 }
@@ -3277,9 +3402,19 @@
  */
 HRESULT WINAPI VarBstrFromCy(CY cyIn, LCID lcid, ULONG dwFlags, BSTR *pbstrOut) {
-	FIXME("([cyIn], %08lx, %08lx, %p), stub.\n", lcid, dwFlags, pbstrOut);
-	return E_NOTIMPL;
-}
-
- 
+    HRESULT rc = S_OK;
+    double curVal = 0.0;
+
+	TRACE("([cyIn], %08lx, %08lx, %p), partial stub (no flags handled).\n", lcid, dwFlags, pbstrOut);
+
+    /* Firstly get the currency in a double, then put it in a buffer */
+    rc = VarR8FromCy(cyIn, &curVal);
+    if (rc == S_OK) {
+        sprintf(pBuffer, "%g", curVal);
+        *pbstrOut = StringDupAtoBstr( pBuffer );
+    }
+	return rc;
+}
+
+
 /******************************************************************************
  *		VarBstrFromDate		[OLEAUT32.114]
@@ -3316,5 +3451,5 @@
     memset( &TM, 0, sizeof(TM) );
 
-    TRACE("( %f, %ld, %ld, %p ), stub\n", dateIn, lcid, dwFlags, pbstrOut );
+    TRACE("( %20.20f, %ld, %ld, %p ), stub\n", dateIn, lcid, dwFlags, pbstrOut );
 
     if( DateToTm( dateIn, dwFlags, &TM ) == FALSE )
@@ -3330,6 +3465,6 @@
         strftime( pBuffer, BUFFER_MAX, "%x %X", &TM );
 
+        TRACE("result: %s\n", pBuffer);
 		*pbstrOut = StringDupAtoBstr( pBuffer );
-
 	return S_OK;
 }
@@ -3508,5 +3643,5 @@
 
 	HeapFree( GetProcessHeap(), 0, pNewString );
-	
+
 	return ret;
 }
@@ -3555,5 +3690,5 @@
       if (cyIn.s.Hi || cyIn.s.Lo) *pboolOut = -1;
       else *pboolOut = 0;
-      
+
       return S_OK;
 }
@@ -3688,5 +3823,5 @@
 	 */
 	dValue = atof( pNewString );
-  
+
 	/* We don't need the string anymore so free it.
 	 */
@@ -3758,7 +3893,7 @@
 HRESULT WINAPI VarI1FromCy(CY cyIn, CHAR* pcOut) {
    double t = round((((double)cyIn.s.Hi * 4294967296.0) + (double)cyIn.s.Lo) / 10000);
-   
+
    if (t > CHAR_MAX || t < CHAR_MIN) return DISP_E_OVERFLOW;
-   
+
    *pcOut = (CHAR)t;
    return S_OK;
@@ -3887,5 +4022,5 @@
 	 */
 	dValue = atof( pNewString );
-  
+
 	/* We don't need the string anymore so free it.
 	 */
@@ -3936,5 +4071,5 @@
 	TRACE("( %ld, %p ), stub\n", ulIn, puiOut );
 
-	if( ulIn < UI2_MIN || ulIn > UI2_MAX )
+	if( ulIn > UI2_MAX )
 	{
 		return DISP_E_OVERFLOW;
@@ -3968,5 +4103,5 @@
 	 */
 	dValue = atof( pNewString );
-  
+
 	/* We don't need the string anymore so free it.
 	 */
@@ -3992,9 +4127,9 @@
 HRESULT WINAPI VarUI2FromCy(CY cyIn, USHORT* pusOut) {
    double t = round((((double)cyIn.s.Hi * 4294967296.0) + (double)cyIn.s.Lo) / 10000);
-   
+
    if (t > UI2_MAX || t < UI2_MIN) return DISP_E_OVERFLOW;
-      
+
    *pusOut = (USHORT)t;
-   
+
    return S_OK;
 }
@@ -4036,5 +4171,5 @@
 	TRACE("( %ld, %p ), stub\n", lIn, pulOut );
 
-	if( lIn < UI4_MIN )
+	if( lIn < 0 )
 	{
 		return DISP_E_OVERFLOW;
@@ -4140,5 +4275,5 @@
 HRESULT WINAPI VarUI4FromCy(CY cyIn, ULONG* pulOut) {
    double t = round((((double)cyIn.s.Hi * 4294967296.0) + (double)cyIn.s.Lo) / 10000);
-   
+
    if (t > UI4_MAX || t < UI4_MIN) return DISP_E_OVERFLOW;
 
@@ -4180,5 +4315,5 @@
       pcyOut->s.Lo = (ULONG)fmod(t, (double)4294967296.0);
       if (lIn < 0) pcyOut->s.Hi--;
-   
+
       return S_OK;
 }
@@ -4193,5 +4328,5 @@
    pcyOut->s.Lo = (ULONG)fmod(t, (double)4294967296.0);
    if (fltIn < 0) pcyOut->s.Hi--;
-   
+
    return S_OK;
 }
@@ -4225,11 +4360,57 @@
 /**********************************************************************
  *              VarCyFromStr [OLEAUT32.104]
+ * FIXME: Never tested with decimal seperator other than '.'
  */
 HRESULT WINAPI VarCyFromStr(OLECHAR *strIn, LCID lcid, ULONG dwFlags, CY *pcyOut) {
-	FIXME("(%p, %08lx, %08lx, %p), stub.\n", strIn, lcid, dwFlags, pcyOut);
-	return E_NOTIMPL;
-}
-
- 
+
+	LPSTR   pNewString      = NULL;
+    char   *decSep          = NULL;
+    char   *strPtr,*curPtr  = NULL;
+    int size, rc;
+    double currencyVal = 0.0;
+
+
+	pNewString = HEAP_strdupWtoA( GetProcessHeap(), 0, strIn );
+	TRACE("( '%s', 0x%08lx, 0x%08lx, %p )\n", pNewString, lcid, dwFlags, pcyOut );
+
+    /* Get locale information - Decimal Seperator (size includes 0x00) */
+    size = GetLocaleInfoA(lcid, LOCALE_SDECIMAL, NULL, 0);
+    decSep = (char *) malloc(size);
+    rc = GetLocaleInfoA(lcid, LOCALE_SDECIMAL, decSep, size);
+    TRACE("Decimal Seperator is '%s'\n", decSep);
+
+    /* Now copy to temporary buffer, skipping any character except 0-9 and
+       the decimal seperator */
+    curPtr = pBuffer;      /* Current position in string being built       */
+    strPtr = pNewString;   /* Current position in supplied currenct string */
+
+    while (*strPtr) {
+        /* If decimal seperator, skip it and put '.' in string */
+        if (strncmp(strPtr, decSep, (size-1)) == 0) {
+            strPtr = strPtr + (size-1);
+            *curPtr = '.';
+            curPtr++;
+        } else if ((*strPtr == '+' || *strPtr == '-') ||
+                   (*strPtr >= '0' && *strPtr <= '9')) {
+            *curPtr = *strPtr;
+            strPtr++;
+            curPtr++;
+        } else strPtr++;
+    }
+    *curPtr = 0x00;
+
+    /* Try to get currency into a double */
+    currencyVal = atof(pBuffer);
+    TRACE("Converted string '%s' to %f\n", pBuffer, currencyVal);
+
+    /* Free allocated storage */
+    HeapFree( GetProcessHeap(), 0, pNewString );
+    free(decSep);
+
+    /* Convert double -> currency using internal routine */
+	return VarCyFromR8(currencyVal, pcyOut);
+}
+
+
 /**********************************************************************
  *              VarCyFromBool [OLEAUT32.106]
@@ -4240,5 +4421,5 @@
    else pcyOut->s.Hi = 0;
    pcyOut->s.Lo = (ULONG)boolIn * (ULONG)10000;
-   
+
    return S_OK;
 }
@@ -4252,5 +4433,5 @@
    else pcyOut->s.Hi = 0;
    pcyOut->s.Lo = (ULONG)cIn * (ULONG)10000;
-   
+
    return S_OK;
 }
@@ -4263,5 +4444,5 @@
    pcyOut->s.Hi = 0;
    pcyOut->s.Lo = (ULONG)usIn * (ULONG)10000;
-   
+
    return S_OK;
 }
@@ -4275,5 +4456,5 @@
    pcyOut->s.Hi = (LONG)(t / (double)4294967296.0);
    pcyOut->s.Lo = (ULONG)fmod(t, (double)4294967296.0);
-      
+
    return S_OK;
 }
@@ -4291,9 +4472,9 @@
 
     TRACE("( 0x%x, 0x%x, %p ), stub\n", wDosDate, wDosTime, pvtime );
-    
+
     t.tm_sec = (wDosTime & 0x001f) * 2;
     t.tm_min = (wDosTime & 0x07e0) >> 5;
     t.tm_hour = (wDosTime & 0xf800) >> 11;
-    
+
     t.tm_mday = (wDosDate & 0x001f);
     t.tm_mon = (wDosDate & 0x01e0) >> 5;
@@ -4312,14 +4493,22 @@
     int i,lastent=0;
     int cDig;
+    BOOL foundNum=FALSE;
+
     FIXME("(%s,flags=%lx,....), partial stub!\n",debugstr_w(strIn),dwFlags);
     FIXME("numparse: cDig=%d, InFlags=%lx\n",pnumprs->cDig,pnumprs->dwInFlags);
 
     /* The other struct components are to be set by us */
-
     memset(rgbDig,0,pnumprs->cDig);
+
+    /* FIXME: Just patching some values in */
+    pnumprs->nPwr10	= 0;
+    pnumprs->nBaseShift	= 0;
+    pnumprs->cchUsed	= lastent;
+    pnumprs->dwOutFlags	= NUMPRS_DECIMAL;
 
     cDig = 0;
     for (i=0; strIn[i] ;i++) {
 	if ((strIn[i]>='0') && (strIn[i]<='9')) {
+            foundNum = TRUE;
 	    if (pnumprs->cDig > cDig) {
 		*(rgbDig++)=strIn[i]-'0';
@@ -4327,13 +4516,10 @@
 		lastent = i;
 	    }
-	}
+	} else if ((strIn[i]=='-') && (foundNum==FALSE)) {
+            pnumprs->dwOutFlags	|= NUMPRS_NEG;
+        }
     }
     pnumprs->cDig	= cDig;
-
-    /* FIXME: Just patching some values in */
-    pnumprs->nPwr10	= 0;
-    pnumprs->nBaseShift	= 0;
-    pnumprs->cchUsed	= lastent;
-    pnumprs->dwOutFlags	= NUMPRS_DECIMAL;
+    TRACE("numparse out: cDig=%d, OutFlags=%lx\n",pnumprs->cDig,pnumprs->dwOutFlags);
     return S_OK;
 }
@@ -4348,9 +4534,13 @@
     DWORD xint;
     int i;
-    FIXME("(,dwVtBits=%lx,....), partial stub!\n",dwVtBits);
+    FIXME("(..,dwVtBits=%lx,....), partial stub!\n",dwVtBits);
 
     xint = 0;
     for (i=0;i<pnumprs->cDig;i++)
 	xint = xint*10 + rgbDig[i];
+
+    if (pnumprs->dwOutFlags & NUMPRS_NEG) {
+        xint = xint * -1;
+    }
 
     VariantInit(pvar);
@@ -4364,10 +4554,46 @@
 	V_UNION(pvar,dblVal) = xint;
 	return S_OK;
-    } else {
-	FIXME("vtbitmask is unsupported %lx\n",dwVtBits);
+    }
+    if (dwVtBits & VTBIT_R4) {
+	V_VT(pvar) = VT_R4;
+	V_UNION(pvar,fltVal) = xint;
+	return S_OK;
+    }
+    if (dwVtBits & VTBIT_I2) {
+        V_VT(pvar) = VT_I2;
+        V_UNION(pvar,iVal) = xint;
+        return S_OK;
+    }
+    /* FIXME: Currency should be from a double */
+    if (dwVtBits & VTBIT_CY) {
+        V_VT(pvar) = VT_CY;
+        TRACE("Calculated currency is xint=%ld\n", xint);
+        VarCyFromInt( (int) xint, &V_UNION(pvar,cyVal) );
+        TRACE("Calculated cy is %ld,%lu\n", V_UNION(pvar,cyVal).s.Hi, V_UNION(pvar,cyVal).s.Lo);
+        return VarCyFromInt( (int) xint, &V_UNION(pvar,cyVal) );
+    }
+
+	FIXME("vtbitmask is unsupported %lx, int=%d\n",dwVtBits, (int) xint);
 	return E_FAIL;
-    }
-}
-
+}
+
+
+/**********************************************************************
+ *              VarFormatDateTime [OLEAUT32.97]
+ */
+HRESULT WINAPI VarFormatDateTime(LPVARIANT var, INT format, ULONG dwFlags, BSTR *out)
+{
+    FIXME("%p %d %lx %p\n", var, format, dwFlags, out);
+    return E_NOTIMPL;
+}
+
+/**********************************************************************
+ *              VarFormatCurrency [OLEAUT32.127]
+ */
+HRESULT WINAPI VarFormatCurrency(LPVARIANT var, INT digits, INT lead, INT paren, INT group, ULONG dwFlags, BSTR *out)
+{
+    FIXME("%p %d %d %d %d %lx %p\n", var, digits, lead, paren, group, dwFlags, out);
+    return E_NOTIMPL;
+}
 
 /**********************************************************************
@@ -4403,7 +4629,4 @@
 HRESULT WINAPI SystemTimeToVariantTime( LPSYSTEMTIME  lpSystemTime, double *pvtime )
 {
-    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};
-
     struct tm t;
 
@@ -4420,5 +4643,5 @@
 
         t.tm_mday = lpSystemTime->wDay;
-        t.tm_mon = lpSystemTime->wMonth;
+        t.tm_mon = lpSystemTime->wMonth - 1; /* tm_mon is 0..11, wMonth is 1..12 */
         t.tm_year = lpSystemTime->wYear;
 
@@ -4427,19 +4650,51 @@
     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;
 
-        if (isleap(lpSystemTime->wYear) )
-            t.tm_mday = Days_Per_Month_LY[13 - lpSystemTime->wMonth] - lpSystemTime->wDay;
-        else
-            t.tm_mday = Days_Per_Month[13 - lpSystemTime->wMonth] - lpSystemTime->wDay;
-
-        t.tm_mon = 13 - lpSystemTime->wMonth;
+        /* 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 );
 
-        *pvtime *= -1;
+        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;
@@ -4468,5 +4723,5 @@
     struct tm r;
 
-    TRACE(" Variant = %f SYSTEMTIME ptr %p", vtime, lpSystemTime);
+    TRACE(" Variant = %f SYSTEMTIME ptr %p\n", vtime, lpSystemTime);
 
     if (vtime >= 0)
@@ -4619,15 +4874,13 @@
     *datein = t;
 
-    if (i) dwFlags = 0; /*VAR_VALIDDATE*/
-    else dwFlags = 0;
-
-    return i;
+    if (i) return S_OK;
+    else return E_INVALIDARG;
 }
 
 
 /**********************************************************************
- *              VarBstrCmp [OLEAUT32.440]
+ *              VarBstrCmp [OLEAUT32.314]
  *
- * flags can be: 
+ * flags can be:
  *   NORM_IGNORECASE, NORM_IGNORENONSPACE, NORM_IGNORESYMBOLS
  *   NORM_IGNORESTRINGWIDTH, NORM_IGNOREKANATYPE, NORM_IGNOREKASHIDA
@@ -4636,10 +4889,15 @@
 HRESULT WINAPI VarBstrCmp(BSTR left, BSTR right, LCID lcid, DWORD flags)
 {
-    DWORD r;
-
-    FIXME("( %s %s %ld %lx ) partial stub\n", debugstr_w(left), debugstr_w(right), lcid, flags);
-
-    if((!left) || (!right))
-        return VARCMP_NULL;
+    INT r;
+
+    TRACE("( %s %s %ld %lx ) partial stub\n", debugstr_w(left), debugstr_w(right), lcid, flags);
+
+    /* Contrary to the MSDN, this returns eq for null vs null, null vs L"" and L"" vs NULL */
+    if((!left) || (!right)) {
+
+        if (!left && (!right || *right==0)) return VARCMP_EQ;
+        else if (!right && (!left || *left==0)) return VARCMP_EQ;
+        else return VARCMP_NULL;
+    }
 
     if(flags&NORM_IGNORECASE)
@@ -4657,25 +4915,29 @@
 
 /**********************************************************************
- *              VarBstrCat [OLEAUT32.439]
+ *              VarBstrCat [OLEAUT32.313]
  */
 HRESULT WINAPI VarBstrCat(BSTR left, BSTR right, BSTR *out)
 {
     BSTR result;
+    int size = 0;
 
     TRACE("( %s %s %p )\n", debugstr_w(left), debugstr_w(right), out);
 
-    if( (!left) || (!right) || (!out) )
-        return 0;
-
-    result = SysAllocStringLen(left, lstrlenW(left)+lstrlenW(right));
-    lstrcatW(result,right);
-
-    *out = result;
-
-    return 1;
+    /* On Windows, NULL parms are still handled (as empty strings) */
+    if (left)  size=size + lstrlenW(left);
+    if (right) size=size + lstrlenW(right);
+
+    if (out) {
+        result = SysAllocStringLen(NULL, size);
+        *out = result;
+        if (left) lstrcatW(result,left);
+        if (right) lstrcatW(result,right);
+        TRACE("result = %s, [%p]\n", debugstr_w(result), result);
+    }
+    return S_OK;
 }
 
 /**********************************************************************
- *              VarCat [OLEAUT32.441]
+ *              VarCat [OLEAUT32.318]
  */
 HRESULT WINAPI VarCat(LPVARIANT left, LPVARIANT right, LPVARIANT out)
@@ -4699,2 +4961,615 @@
     return S_OK;
 }
+
+/**********************************************************************
+ *              VarCmp [OLEAUT32.176]
+ *
+ * flags can be:
+ *   NORM_IGNORECASE, NORM_IGNORENONSPACE, NORM_IGNORESYMBOLS
+ *   NORM_IGNOREWIDTH, NORM_IGNOREKANATYPE, NORM_IGNOREKASHIDA
+ *
+ */
+HRESULT WINAPI VarCmp(LPVARIANT left, LPVARIANT right, LCID lcid, DWORD flags)
+{
+
+
+    BOOL         lOk        = TRUE;
+    BOOL         rOk        = TRUE;
+    LONGLONG     lVal = -1;
+    LONGLONG     rVal = -1;
+
+    TRACE("Left Var:\n");
+    dump_Variant(left);
+    TRACE("Right Var:\n");
+    dump_Variant(right);
+
+    /* If either are null, then return VARCMP_NULL */
+    if ((V_VT(left)&VT_TYPEMASK) == VT_NULL ||
+        (V_VT(right)&VT_TYPEMASK) == VT_NULL)
+        return VARCMP_NULL;
+
+    /* Strings - use VarBstrCmp */
+    if ((V_VT(left)&VT_TYPEMASK) == VT_BSTR &&
+        (V_VT(right)&VT_TYPEMASK) == VT_BSTR) {
+        return VarBstrCmp(V_BSTR(left), V_BSTR(right), lcid, flags);
+    }
+
+    /* Integers - Ideally like to use VarDecCmp, but no Dec support yet
+           Use LONGLONG to maximize ranges                              */
+    lOk = TRUE;
+    switch (V_VT(left)&VT_TYPEMASK) {
+    case VT_I1   : lVal = V_UNION(left,cVal); break;
+    case VT_I2   : lVal = V_UNION(left,iVal); break;
+    case VT_I4   : lVal = V_UNION(left,lVal); break;
+    case VT_INT  : lVal = V_UNION(left,lVal); break;
+    case VT_UI1  : lVal = V_UNION(left,bVal); break;
+    case VT_UI2  : lVal = V_UNION(left,uiVal); break;
+    case VT_UI4  : lVal = V_UNION(left,ulVal); break;
+    case VT_UINT : lVal = V_UNION(left,ulVal); break;
+    default: lOk = FALSE;
+    }
+
+    rOk = TRUE;
+    switch (V_VT(right)&VT_TYPEMASK) {
+    case VT_I1   : rVal = V_UNION(right,cVal); break;
+    case VT_I2   : rVal = V_UNION(right,iVal); break;
+    case VT_I4   : rVal = V_UNION(right,lVal); break;
+    case VT_INT  : rVal = V_UNION(right,lVal); break;
+    case VT_UI1  : rVal = V_UNION(right,bVal); break;
+    case VT_UI2  : rVal = V_UNION(right,uiVal); break;
+    case VT_UI4  : rVal = V_UNION(right,ulVal); break;
+    case VT_UINT : rVal = V_UNION(right,ulVal); break;
+    default: rOk = FALSE;
+    }
+
+    if (lOk && rOk) {
+        if (lVal < rVal) {
+            return VARCMP_LT;
+        } else if (lVal > rVal) {
+            return VARCMP_GT;
+        } else {
+            return VARCMP_EQ;
+        }
+    }
+
+    /* Strings - use VarBstrCmp */
+    if ((V_VT(left)&VT_TYPEMASK) == VT_DATE &&
+        (V_VT(right)&VT_TYPEMASK) == VT_DATE) {
+
+        if (floor(V_UNION(left,date)) == floor(V_UNION(right,date))) {
+            /* Due to floating point rounding errors, calculate varDate in whole numbers) */
+            double wholePart = 0.0;
+            double leftR;
+            double rightR;
+
+            /* Get the fraction * 24*60*60 to make it into whole seconds */
+            wholePart = (double) floor( V_UNION(left,date) );
+            if (wholePart == 0) wholePart = 1;
+            leftR = floor(fmod( V_UNION(left,date), wholePart ) * (24*60*60));
+
+            wholePart = (double) floor( V_UNION(right,date) );
+            if (wholePart == 0) wholePart = 1;
+            rightR = floor(fmod( V_UNION(right,date), wholePart ) * (24*60*60));
+
+            if (leftR < rightR) {
+                return VARCMP_LT;
+            } else if (leftR > rightR) {
+                return VARCMP_GT;
+            } else {
+                return VARCMP_EQ;
+            }
+
+        } else if (V_UNION(left,date) < V_UNION(right,date)) {
+            return VARCMP_LT;
+        } else if (V_UNION(left,date) > V_UNION(right,date)) {
+            return VARCMP_GT;
+        }
+    }
+
+
+    FIXME("VarCmp partial implementation, doesnt support these pair of variant types");
+    return E_FAIL;
+}
+
+/**********************************************************************
+ *              VarAnd [OLEAUT32.142]
+ *
+ */
+HRESULT WINAPI VarAnd(LPVARIANT left, LPVARIANT right, LPVARIANT result)
+{
+    HRESULT rc = E_FAIL;
+
+
+    TRACE("Left Var:\n");
+    dump_Variant(left);
+    TRACE("Right Var:\n");
+    dump_Variant(right);
+
+    if ((V_VT(left)&VT_TYPEMASK) == VT_BOOL &&
+        (V_VT(right)&VT_TYPEMASK) == VT_BOOL) {
+
+        V_VT(result) = VT_BOOL;
+        if (V_BOOL(left) && V_BOOL(right)) {
+            V_BOOL(result) = VARIANT_TRUE;
+        } else {
+            V_BOOL(result) = VARIANT_FALSE;
+        }
+        rc = S_OK;
+
+    } else {
+        FIXME("VarAnd stub\n");
+    }
+
+    TRACE("rc=%d, Result:\n", (int) rc);
+    dump_Variant(result);
+    return rc;
+}
+
+/**********************************************************************
+ *              VarNot [OLEAUT32.174]
+ *
+ */
+HRESULT WINAPI VarNot(LPVARIANT in, LPVARIANT result)
+{
+    HRESULT rc = E_FAIL;
+
+    TRACE("Var In:\n");
+    dump_Variant(in);
+
+    if ((V_VT(in)&VT_TYPEMASK) == VT_BOOL) {
+
+        V_VT(result) = VT_BOOL;
+        if (V_BOOL(in)) {
+            V_BOOL(result) = VARIANT_FALSE;
+        } else {
+            V_BOOL(result) = VARIANT_TRUE;
+        }
+        rc = S_OK;
+
+    } else {
+        FIXME("VarNot stub\n");
+    }
+
+    TRACE("rc=%d, Result:\n", (int) rc);
+    dump_Variant(result);
+    return rc;
+}
+
+/**********************************************************************
+ *              VarTokenizeFormatString [OLEAUT32.140]
+ *
+ * From investigation on W2K, a list is built up which is:
+ *
+ * <0x00> AA BB - Copy from AA for BB chars (Note 1 byte with wrap!)
+ * <token> - Insert appropriate token
+ *
+ */
+HRESULT WINAPI VarTokenizeFormatString(LPOLESTR  format, LPBYTE rgbTok,
+                     int   cbTok, int iFirstDay, int iFirstWeek,
+                     LCID  lcid, int *pcbActual) {
+
+    FORMATHDR *hdr;
+    int        realLen, formatLeft;
+    BYTE      *pData;
+    LPSTR      pFormatA, pStart;
+    int        checkStr;
+    BOOL       insertCopy = FALSE;
+    LPSTR      copyFrom = NULL;
+
+    TRACE("'%s', %p %d %d %d only date support\n", debugstr_w(format), rgbTok, cbTok,
+                   iFirstDay, iFirstWeek);
+
+    /* Big enough for header? */
+    if (cbTok < sizeof(FORMATHDR)) {
+        return TYPE_E_BUFFERTOOSMALL;
+    }
+
+    /* Insert header */
+    hdr = (FORMATHDR *) rgbTok;
+    memset(hdr, 0x00, sizeof(FORMATHDR));
+    hdr->hex3 = 0x03; /* No idea what these are */
+    hdr->hex6 = 0x06;
+
+    /* Start parsing string */
+    realLen    = sizeof(FORMATHDR);
+    pData      = rgbTok + realLen;
+    pFormatA   = HEAP_strdupWtoA( GetProcessHeap(), 0, format );
+    pStart     = pFormatA;
+    formatLeft = strlen(pFormatA);
+
+    /* Work through the format */
+    while (*pFormatA != 0x00) {
+
+        checkStr = 0;
+        while (checkStr>=0 && (formatTokens[checkStr].tokenSize != 0x00)) {
+            if (formatLeft >= formatTokens[checkStr].tokenSize &&
+                strncmp(formatTokens[checkStr].str, pFormatA,
+                        formatTokens[checkStr].tokenSize) == 0) {
+                TRACE("match on '%s'\n", formatTokens[checkStr].str);
+
+                /* Found Match! */
+
+                /* If we have skipped chars, insert the copy */
+                if (insertCopy == TRUE) {
+
+                    if ((realLen + 3) > cbTok) {
+                        HeapFree( GetProcessHeap(), 0, pFormatA );
+                        return TYPE_E_BUFFERTOOSMALL;
+                    }
+                    insertCopy = FALSE;
+                    *pData = TOK_COPY;
+                    pData++;
+                    *pData = (BYTE)(copyFrom - pStart);
+                    pData++;
+                    *pData = (BYTE)(pFormatA - copyFrom);
+                    pData++;
+                    realLen = realLen + 3;
+                }
+
+
+                /* Now insert the token itself */
+                if ((realLen + 1) > cbTok) {
+                    HeapFree( GetProcessHeap(), 0, pFormatA );
+                    return TYPE_E_BUFFERTOOSMALL;
+                }
+                *pData = formatTokens[checkStr].tokenId;
+                pData = pData + 1;
+                realLen = realLen + 1;
+
+                pFormatA = pFormatA + formatTokens[checkStr].tokenSize;
+                formatLeft = formatLeft - formatTokens[checkStr].tokenSize;
+                checkStr = -1; /* Flag as found and break out of while loop */
+            } else {
+                checkStr++;
+            }
+        }
+
+        /* Did we ever match a token? */
+        if (checkStr != -1 && insertCopy == FALSE) {
+            TRACE("No match - need to insert copy from %p [%p]\n", pFormatA, pStart);
+            insertCopy = TRUE;
+            copyFrom   = pFormatA;
+        } else if (checkStr != -1) {
+            pFormatA = pFormatA + 1;
+        }
+
+    }
+
+    /* Finally, if we have skipped chars, insert the copy */
+    if (insertCopy == TRUE) {
+
+        TRACE("Chars left over, so still copy %p,%p,%p\n", copyFrom, pStart, pFormatA);
+        if ((realLen + 3) > cbTok) {
+            HeapFree( GetProcessHeap(), 0, pFormatA );
+            return TYPE_E_BUFFERTOOSMALL;
+        }
+        insertCopy = FALSE;
+        *pData = TOK_COPY;
+        pData++;
+        *pData = (BYTE)(copyFrom - pStart);
+        pData++;
+        *pData = (BYTE)(pFormatA - copyFrom);
+        pData++;
+        realLen = realLen + 3;
+    }
+
+    /* Finally insert the terminator */
+    if ((realLen + 1) > cbTok) {
+        HeapFree( GetProcessHeap(), 0, pFormatA );
+        return TYPE_E_BUFFERTOOSMALL;
+    }
+    *pData++ = TOK_END;
+    realLen = realLen + 1;
+
+    /* Finally fill in the length */
+    hdr->len = realLen;
+    *pcbActual = realLen;
+
+#if 0
+    { int i,j;
+      for (i=0; i<realLen; i=i+0x10) {
+          printf(" %4.4x : ", i);
+          for (j=0; j<0x10 && (i+j < realLen); j++) {
+              printf("%2.2x ", rgbTok[i+j]);
+          }
+          printf("\n");
+      }
+    }
+#endif
+    HeapFree( GetProcessHeap(), 0, pFormatA );
+
+    return S_OK;
+}
+
+/**********************************************************************
+ *              VarFormatFromTokens [OLEAUT32.139]
+ * FIXME: No account of flags or iFirstDay etc
+ */
+HRESULT WINAPI VarFormatFromTokens(LPVARIANT varIn, LPOLESTR format,
+                            LPBYTE pbTokCur, ULONG dwFlags, BSTR *pbstrOut,
+                            LCID  lcid) {
+
+    FORMATHDR   *hdr = (FORMATHDR *)pbTokCur;
+    BYTE        *pData    = pbTokCur + sizeof (FORMATHDR);
+    LPSTR        pFormatA = HEAP_strdupWtoA( GetProcessHeap(), 0, format );
+    char         output[BUFFER_MAX];
+    char        *pNextPos;
+    int          size, whichToken;
+    VARIANTARG   Variant;
+    struct tm    TM;
+
+
+
+    TRACE("'%s', %p %lx %p only date support\n", pFormatA, pbTokCur, dwFlags, pbstrOut);
+    TRACE("varIn:\n");
+    dump_Variant(varIn);
+
+    memset(output, 0x00, BUFFER_MAX);
+    pNextPos = output;
+
+    while (*pData != TOK_END && ((pData - pbTokCur) <= (hdr->len))) {
+
+        TRACE("Output looks like : '%s'\n", output);
+
+        /* Convert varient to appropriate data type */
+        whichToken = 0;
+        while ((formatTokens[whichToken].tokenSize != 0x00) &&
+               (formatTokens[whichToken].tokenId   != *pData)) {
+            whichToken++;
+        }
+
+        /* Use Variant local from here downwards as always correct type */
+        if (formatTokens[whichToken].tokenSize > 0 &&
+            formatTokens[whichToken].varTypeRequired != 0) {
+			VariantInit( &Variant );
+            if (Coerce( &Variant, lcid, dwFlags, varIn,
+                        formatTokens[whichToken].varTypeRequired ) != S_OK) {
+                HeapFree( GetProcessHeap(), 0, pFormatA );
+                return DISP_E_TYPEMISMATCH;
+            } else if (formatTokens[whichToken].varTypeRequired == VT_DATE) {
+                if( DateToTm( V_UNION(&Variant,date), dwFlags, &TM ) == FALSE ) {
+                    HeapFree( GetProcessHeap(), 0, pFormatA );
+                    return E_INVALIDARG;
+                }
+            }
+        }
+
+        TRACE("Looking for match on token '%x'\n", *pData);
+        switch (*pData) {
+        case TOK_COPY:
+            TRACE("Copy from %d for %d bytes\n", *(pData+1), *(pData+2));
+            memcpy(pNextPos, &pFormatA[*(pData+1)], *(pData+2));
+            pNextPos = pNextPos + *(pData+2);
+            pData = pData + 3;
+            break;
+
+        case TOK_COLON   :
+            /* Get locale information - Time Seperator */
+            size = GetLocaleInfoA(lcid, LOCALE_STIME, NULL, 0);
+            GetLocaleInfoA(lcid, LOCALE_STIME, pNextPos, size);
+            TRACE("TOK_COLON Time seperator is '%s'\n", pNextPos);
+            pNextPos = pNextPos + size;
+            pData = pData + 1;
+            break;
+
+        case TOK_SLASH   :
+            /* Get locale information - Date Seperator */
+            size = GetLocaleInfoA(lcid, LOCALE_SDATE, NULL, 0);
+            GetLocaleInfoA(lcid, LOCALE_SDATE, pNextPos, size);
+            TRACE("TOK_COLON Time seperator is '%s'\n", pNextPos);
+            pNextPos = pNextPos + size;
+            pData = pData + 1;
+            break;
+
+        case TOK_d       :
+            sprintf(pNextPos, "%d", TM.tm_mday);
+            pNextPos = pNextPos + strlen(pNextPos);
+            pData = pData + 1;
+            break;
+
+        case TOK_dd      :
+            sprintf(pNextPos, "%2.2d", TM.tm_mday);
+            pNextPos = pNextPos + strlen(pNextPos);
+            pData = pData + 1;
+            break;
+
+        case TOK_w       :
+            sprintf(pNextPos, "%d", TM.tm_wday+1);
+            pNextPos = pNextPos + strlen(pNextPos);
+            pData = pData + 1;
+            break;
+
+        case TOK_m       :
+            sprintf(pNextPos, "%d", TM.tm_mon+1);
+            pNextPos = pNextPos + strlen(pNextPos);
+            pData = pData + 1;
+            break;
+
+        case TOK_mm      :
+            sprintf(pNextPos, "%2.2d", TM.tm_mon+1);
+            pNextPos = pNextPos + strlen(pNextPos);
+            pData = pData + 1;
+            break;
+
+        case TOK_q       :
+            sprintf(pNextPos, "%d", ((TM.tm_mon+1)/4)+1);
+            pNextPos = pNextPos + strlen(pNextPos);
+            pData = pData + 1;
+            break;
+
+        case TOK_y       :
+            sprintf(pNextPos, "%2.2d", TM.tm_yday+1);
+            pNextPos = pNextPos + strlen(pNextPos);
+            pData = pData + 1;
+            break;
+
+        case TOK_yy      :
+            sprintf(pNextPos, "%2.2d", TM.tm_year);
+            pNextPos = pNextPos + strlen(pNextPos);
+            pData = pData + 1;
+            break;
+
+        case TOK_yyyy    :
+            sprintf(pNextPos, "%4.4d", TM.tm_year);
+            pNextPos = pNextPos + strlen(pNextPos);
+            pData = pData + 1;
+            break;
+
+        case TOK_h       :
+            sprintf(pNextPos, "%d", TM.tm_hour);
+            pNextPos = pNextPos + strlen(pNextPos);
+            pData = pData + 1;
+            break;
+
+        case TOK_Hh      :
+            sprintf(pNextPos, "%2.2d", TM.tm_hour);
+            pNextPos = pNextPos + strlen(pNextPos);
+            pData = pData + 1;
+            break;
+
+        case TOK_N       :
+            sprintf(pNextPos, "%d", TM.tm_min);
+            pNextPos = pNextPos + strlen(pNextPos);
+            pData = pData + 1;
+            break;
+
+        case TOK_Nn      :
+            sprintf(pNextPos, "%2.2d", TM.tm_min);
+            pNextPos = pNextPos + strlen(pNextPos);
+            pData = pData + 1;
+            break;
+
+        case TOK_S       :
+            sprintf(pNextPos, "%d", TM.tm_sec);
+            pNextPos = pNextPos + strlen(pNextPos);
+            pData = pData + 1;
+            break;
+
+        case TOK_Ss      :
+            sprintf(pNextPos, "%2.2d", TM.tm_sec);
+            pNextPos = pNextPos + strlen(pNextPos);
+            pData = pData + 1;
+            break;
+
+        /* FIXME: To Do! */
+        case TOK_ttttt   :
+        case TOK_AMsPM   :
+        case TOK_amspm   :
+        case TOK_AsP     :
+        case TOK_asp     :
+        case TOK_AMPM    :
+        case TOK_c       :
+        case TOK_ddd     :
+        case TOK_dddd    :
+        case TOK_ddddd   :
+        case TOK_dddddd  :
+        case TOK_ww      :
+        case TOK_mmm     :
+        case TOK_mmmm    :
+        default:
+            FIXME("Unhandled token for VarFormat %d\n", *pData);
+            HeapFree( GetProcessHeap(), 0, pFormatA );
+            return E_INVALIDARG;
+        }
+
+    }
+
+    *pbstrOut = StringDupAtoBstr( output );
+    HeapFree( GetProcessHeap(), 0, pFormatA );
+    return S_OK;
+}
+
+/**********************************************************************
+ *              VarFormat [OLEAUT32.87]
+ *
+ */
+HRESULT WINAPI VarFormat(LPVARIANT varIn, LPOLESTR format,
+                         int firstDay, int firstWeek, ULONG dwFlags,
+                         BSTR *pbstrOut) {
+
+    LPSTR   pNewString = NULL;
+    HRESULT rc = S_OK;
+
+    TRACE("mostly stub! format='%s' day=%d, wk=%d, flags=%ld\n",
+          debugstr_w(format), firstDay, firstWeek, dwFlags);
+    TRACE("varIn:\n");
+    dump_Variant(varIn);
+
+    /* Note: Must Handle references type Variants (contain ptrs
+          to values rather than values */
+
+    /* Get format string */
+    pNewString = HEAP_strdupWtoA( GetProcessHeap(), 0, format );
+
+    /* FIXME: Handle some simple pre-definted format strings : */
+    if (((V_VT(varIn)&VT_TYPEMASK) == VT_CY) && (lstrcmpiA(pNewString, "Currency") == 0)) {
+
+        /* Can't use VarBstrFromCy as it does not put currency sign on nor decimal places */
+        double curVal;
+
+
+        /* Handle references type Variants (contain ptrs to values rather than values */
+        if (V_VT(varIn)&VT_BYREF) {
+            rc = VarR8FromCy(*(CY *)V_UNION(varIn,byref), &curVal);
+        } else {
+            rc = VarR8FromCy(V_UNION(varIn,cyVal), &curVal);
+        }
+
+        if (rc == S_OK) {
+            char tmpStr[BUFFER_MAX];
+            sprintf(tmpStr, "%f", curVal);
+            if (GetCurrencyFormatA(GetUserDefaultLCID(), dwFlags, tmpStr, NULL, pBuffer, BUFFER_MAX) == 0) {
+                return E_FAIL;
+            } else {
+                *pbstrOut = StringDupAtoBstr( pBuffer );
+            }
+        }
+
+    } else if ((V_VT(varIn)&VT_TYPEMASK) == VT_DATE) {
+
+        /* Attempt to do proper formatting! */
+        int firstToken = -1;
+
+        rc = VarTokenizeFormatString(format, pBuffer, sizeof(pBuffer), firstDay,
+                                  firstWeek, GetUserDefaultLCID(), &firstToken);
+        if (rc==S_OK) {
+            rc = VarFormatFromTokens(varIn, format, pBuffer, dwFlags, pbstrOut, GetUserDefaultLCID());
+        }
+
+    } else if ((V_VT(varIn)&VT_TYPEMASK) == VT_R8) {
+        if (V_VT(varIn)&VT_BYREF) {
+            sprintf(pBuffer, "%f", *(double *)V_UNION(varIn,byref));
+        } else {
+            sprintf(pBuffer, "%f", V_UNION(varIn,dblVal));
+        }
+
+        *pbstrOut = StringDupAtoBstr( pBuffer );
+
+    } else {
+        FIXME("VarFormat: Unsupported format %d!\n", V_VT(varIn)&VT_TYPEMASK);
+        *pbstrOut = StringDupAtoBstr( "??" );
+    }
+
+    /* Free allocated storage */
+    HeapFree( GetProcessHeap(), 0, pNewString );
+    TRACE("result: '%s'\n", debugstr_w(*pbstrOut));
+    return rc;
+}
+
+/**********************************************************************
+ *              VarCyMulI4 [OLEAUT32.304]
+ * Multiply currency value by integer
+ */
+HRESULT WINAPI VarCyMulI4(CY cyIn, LONG mulBy, CY *pcyOut) {
+
+    double cyVal = 0;
+    HRESULT rc = S_OK;
+
+    rc = VarR8FromCy(cyIn, &cyVal);
+    if (rc == S_OK) {
+        rc = VarCyFromR8((cyVal * (double) mulBy), pcyOut);
+        TRACE("Multiply %f by %ld = %f [%ld,%lu]\n", cyVal, mulBy, (cyVal * (double) mulBy),
+                    pcyOut->s.Hi, pcyOut->s.Lo);
+    }
+    return rc;
+}
