Commit in reactos on MAIN
doc/README.WINE+1-11.20 -> 1.21
lib/oleaut32/oleaut32_Pl.rc+32added 1.1
            /winehq2ros.patch+33added 1.1
            /.cvsignore+3-21.5 -> 1.6
            /Makefile.in+5-41.7 -> 1.8
            /connpt.c+15-211.2 -> 1.3
            /dispatch.c+7-271.2 -> 1.3
            /hash.c+2-41.1 -> 1.2
            /oaidl_p.c+21.2 -> 1.3
            /oleaut.c+26-51.4 -> 1.5
            /oleaut32.rc+2-11.5 -> 1.6
            /oleaut32.spec+26-261.8 -> 1.9
            /oleaut32_De.rc+1-11.1 -> 1.2
            /olefont.c+37-91.2 -> 1.3
            /olepicture.c+567-531.3 -> 1.4
            /safearray.c+25-131.6 -> 1.7
            /tmarshal.c+21.3 -> 1.4
            /typelib.c+216-1541.3 -> 1.4
            /typelib2.c+3-21.3 -> 1.4
            /usrmarshal.c+21.1 -> 1.2
            /varformat.c+4-51.2 -> 1.3
            /variant.c+712-1251.10 -> 1.11
            /variant.h+7-91.3 -> 1.4
            /vartype.c+13-101.9 -> 1.10
w32api/include/oaidl.h+3-21.8 -> 1.9
              /oleauto.h+41.12 -> 1.13
              /winuser.h+41.10 -> 1.11
              /wtypes.h+8-251.5 -> 1.6
+1762-499
2 added + 26 modified, total 28 files
- Update OLEAUT32 to Wine-20041202

reactos/doc
README.WINE 1.20 -> 1.21
diff -u -r1.20 -r1.21
--- README.WINE	20 Oct 2004 20:35:58 -0000	1.20
+++ README.WINE	2 Dec 2004 19:38:48 -0000	1.21
@@ -45,7 +45,7 @@
 reactos/lib/msvidoe		# Out of sync
 reactos/lib/odbc32		# In sync. Depends on port of Linux ODBC.
 reactos/lib/ole32               # Synced to Wine-20041019
-reactos/lib/oleaut32		# Out of sync
+reactos/lib/oleaut32		# Synced to Wine-20041202
 reactos/lib/oledlg              # Synced to Wine-20041019
 reactos/lib/oldpro32		# Out of sync
 reactos/lib/richedit		# Synced to Wine-20041019

reactos/lib/oleaut32
oleaut32_Pl.rc added at 1.1
diff -N oleaut32_Pl.rc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ oleaut32_Pl.rc	2 Dec 2004 19:38:49 -0000	1.1
@@ -0,0 +1,32 @@
+/*
+ * Polish resources for oleaut32
+ *
+ * Copyright 2003 Jon Griffiths
+ * Copyright 2004 Jacek Caban
+ *
+ * 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
+ */
+
+LANGUAGE LANG_POLISH, SUBLANG_DEFAULT 
+
+STRINGTABLE DISCARDABLE
+{
+  IDS_TRUE  "Prawda"
+  IDS_FALSE "Fa�sz"
+  IDS_YES   "Tak"
+  IDS_NO    "Nie"
+  IDS_ON    "W��czone"
+  IDS_OFF   "Wy��czone"
+}

reactos/lib/oleaut32
winehq2ros.patch added at 1.1
diff -N winehq2ros.patch
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ winehq2ros.patch	2 Dec 2004 19:38:49 -0000	1.1
@@ -0,0 +1,33 @@
+--- variant.c	Thu Dec  2 19:30:53 2004
++++ variant.c	Thu Dec  2 19:38:26 2004
+@@ -2390,7 +2390,7 @@
+     ULONG64 tmp;
+     DECIMAL* pDec = &V_DECIMAL(pVarDst);
+ 
+-    DECIMAL_SETZERO(pDec);
++    DECIMAL_SETZERO(*pDec);
+     DEC_LO32(pDec) = 0;
+ 
+     if (pNumprs->dwOutFlags & NUMPRS_NEG)
+--- variant.h	Mon Aug 23 07:35:19 2004
++++ variant.h	Thu Dec  2 19:43:06 2004
+@@ -82,13 +82,13 @@
+ #endif
+ 
+ /* Macros for getting at a DECIMAL's parts */
+-#define DEC_SIGN(d)      ((d)->u.s.sign)
+-#define DEC_SCALE(d)     ((d)->u.s.scale)
+-#define DEC_SIGNSCALE(d) ((d)->u.signscale)
++#define DEC_SIGN(d)      ((d)->sign)
++#define DEC_SCALE(d)     ((d)->scale)
++#define DEC_SIGNSCALE(d) ((d)->signscale)
+ #define DEC_HI32(d)      ((d)->Hi32)
+-#define DEC_MID32(d)     ((d)->u1.s1.Mid32)
+-#define DEC_LO32(d)      ((d)->u1.s1.Lo32)
+-#define DEC_LO64(d)      ((d)->u1.Lo64)
++#define DEC_MID32(d)     ((d)->Mid32)
++#define DEC_LO32(d)      ((d)->Lo32)
++#define DEC_LO64(d)      ((d)->Lo64)
+ 
+ #define DEC_MAX_SCALE    28 /* Maximum scale for a decimal */
+ 

reactos/lib/oleaut32
.cvsignore 1.5 -> 1.6
diff -u -r1.5 -r1.6
--- .cvsignore	2 Nov 2004 19:47:17 -0000	1.5
+++ .cvsignore	2 Dec 2004 19:38:49 -0000	1.6
@@ -1,8 +1,9 @@
 *.coff
 *.dll
-*.sym
-*.o
 *.d
+*.a
+*.o
+*.sym
 *.map
 *.tmp
 Makefile.ros

reactos/lib/oleaut32
Makefile.in 1.7 -> 1.8
diff -u -r1.7 -r1.8
--- Makefile.in	1 Dec 2004 20:06:15 -0000	1.7
+++ Makefile.in	2 Dec 2004 19:38:49 -0000	1.8
@@ -6,10 +6,7 @@
 MODULE    = oleaut32.dll
 IMPORTS   = ole32 rpcrt4 user32 gdi32 advapi32 kernel32 ntdll
 DELAYIMPORTS = comctl32
-ALTNAMES  = ole2disp.dll typelib.dll
-EXTRALIBS = $(LIBUNICODE) -luuid @GIFLIB@ @JPEGLIB@
-
-SPEC_SRCS16 = $(ALTNAMES:.dll=.spec)
+EXTRALIBS = $(LIBUNICODE) -luuid
 
 C_SRCS = \
 	connpt.c \
@@ -34,6 +31,10 @@
 	ole2disp.c \
 	typelib16.c
 
+SPEC_SRCS16 = \
+	ole2disp.spec \
+	typelib.spec
+
 RC_SRCS = oleaut32.rc
 
 SUBDIRS = tests

reactos/lib/oleaut32
connpt.c 1.2 -> 1.3
diff -u -r1.2 -r1.3
--- connpt.c	26 Sep 2004 14:34:22 -0000	1.2
+++ connpt.c	2 Dec 2004 19:38:49 -0000	1.3
@@ -25,6 +25,9 @@
 #include <assert.h>
 #include <stdarg.h>
 #include <string.h>
+
+#define COBJMACROS
+
 #include "winerror.h"
 #include "windef.h"
 #include "winbase.h"
@@ -194,9 +197,7 @@
 {
   ConnectionPointImpl *This = (ConnectionPointImpl *)iface;
   TRACE("(%p)->(ref=%ld)\n", This, This->ref);
-  This->ref++;
-
-  return This->ref;
+  return InterlockedIncrement(&This->ref);
 }
 
 /************************************************************************
@@ -208,24 +209,20 @@
       IConnectionPoint* iface)
 {
   ConnectionPointImpl *This = (ConnectionPointImpl *)iface;
+  ULONG ref;
   TRACE("(%p)->(ref=%ld)\n", This, This->ref);
 
   /*
    * Decrease the reference count on this object.
    */
-  This->ref--;
+  ref = InterlockedDecrement(&This->ref);
 
   /*
    * If the reference count goes down to 0, perform suicide.
    */
-  if (This->ref==0)
-  {
-    ConnectionPointImpl_Destroy(This);
+  if (ref == 0) ConnectionPointImpl_Destroy(This);
 
-    return 0;
-  }
-
-  return This->ref;
+  return ref;
 }
 
 /************************************************************************
@@ -473,10 +470,11 @@
 static ULONG WINAPI EnumConnectionsImpl_AddRef(IEnumConnections* iface)
 {
   EnumConnectionsImpl *This = (EnumConnectionsImpl *)iface;
+  ULONG ref;
   TRACE("(%p)->(ref=%ld)\n", This, This->ref);
-  This->ref++;
+  ref = InterlockedIncrement(&This->ref);
   IUnknown_AddRef(This->pUnk);
-  return This->ref;
+  return ref;
 }
 
 /************************************************************************
@@ -487,6 +485,7 @@
 static ULONG WINAPI EnumConnectionsImpl_Release(IEnumConnections* iface)
 {
   EnumConnectionsImpl *This = (EnumConnectionsImpl *)iface;
+  ULONG ref;
   TRACE("(%p)->(ref=%ld)\n", This, This->ref);
 
   IUnknown_Release(This->pUnk);
@@ -494,19 +493,14 @@
   /*
    * Decrease the reference count on this object.
    */
-  This->ref--;
+  ref = InterlockedDecrement(&This->ref);
 
   /*
    * If the reference count goes down to 0, perform suicide.
    */
-  if (This->ref==0)
-  {
-    EnumConnectionsImpl_Destroy(This);
-
-    return 0;
-  }
+  if (ref == 0) EnumConnectionsImpl_Destroy(This);
 
-  return This->ref;
+  return ref;
 }
 
 /************************************************************************

reactos/lib/oleaut32
dispatch.c 1.2 -> 1.3
diff -u -r1.2 -r1.3
--- dispatch.c	26 Sep 2004 14:34:22 -0000	1.2
+++ dispatch.c	2 Dec 2004 19:38:49 -0000	1.3
@@ -28,6 +28,8 @@
 #include <stdio.h>
 #include <ctype.h>
 
+#define COBJMACROS
+
 #include "windef.h"
 #include "winbase.h"
 #include "objbase.h"
@@ -180,28 +182,6 @@
     return S_OK;
 }
 
-/******************************************************************************
- * CreateDispTypeInfo [OLEAUT32.31]
- *
- * Build type information for an object so it can be called through an
- * IDispatch interface.
- *
- * RETURNS
- *  Success: S_OK. pptinfo contains the created ITypeInfo object.
- *  Failure: E_INVALIDARG, if one or more arguments is invalid.
- *
- * NOTES
- *  This call allows an objects methods to be accessed through IDispatch, by
- *  building an ITypeInfo object that IDispatch can use to call through.
- */
-HRESULT WINAPI CreateDispTypeInfo(
-	INTERFACEDATA *pidata, /* [I] Description of the interface to build type info for */
-	LCID lcid, /* [I] Locale Id */
-	ITypeInfo **pptinfo) /* [O] Destination for created ITypeInfo object */
-{
-	FIXME("(%p,%ld,%p),stub\n",pidata,lcid,pptinfo);
-	return 0;
-}
 
 /******************************************************************************
  * IDispatch {OLEAUT32}
@@ -278,7 +258,7 @@
     StdDispatch *This = (StdDispatch *)iface;
     TRACE("()\n");
 
-    return ++This->ref;
+    return InterlockedIncrement(&This->ref);
 }
 
 /******************************************************************************
@@ -289,18 +269,18 @@
 static ULONG WINAPI StdDispatch_Release(LPDISPATCH iface)
 {
     StdDispatch *This = (StdDispatch *)iface;
-    ULONG ret;
+    ULONG ref;
     TRACE("(%p)->()\n", This);
 
-    ret = This->ref--;
+    ref = InterlockedDecrement(&This->ref);
 
-    if (This->ref == 0)
+    if (ref == 0)
     {
         ITypeInfo_Release(This->pTypeInfo);
         CoTaskMemFree(This);
     }
 
-    return ret;
+    return ref;
 }
 
 /******************************************************************************

reactos/lib/oleaut32
hash.c 1.1 -> 1.2
diff -u -r1.1 -r1.2
--- hash.c	7 Feb 2004 18:53:58 -0000	1.1
+++ hash.c	2 Dec 2004 19:38:49 -0000	1.2
@@ -23,6 +23,7 @@
 #include "windef.h"
 #include "winbase.h"
 #include "winnls.h"
+#include "objbase.h"
 #include "oaidl.h"
 #include "wine/debug.h"
 
@@ -537,9 +538,7 @@
   case LANG_SWEDISH:    case LANG_SYRIAC:     case LANG_TAMIL:
   case LANG_TATAR:      case LANG_TELUGU:     case LANG_THAI:
   case LANG_UKRAINIAN:  case LANG_URDU:       case LANG_UZBEK:
-  case LANG_VIETNAMESE:
-#ifndef __REACTOS__	/* non standard languages */
-  case LANG_GAELIC:     case LANG_MALTESE:
+  case LANG_VIETNAMESE: case LANG_GAELIC:     case LANG_MALTESE:
   case LANG_MAORI:      case LANG_RHAETO_ROMANCE:
   case LANG_SAAMI:      case LANG_SORBIAN:    case LANG_SUTU:
   case LANG_TSONGA:     case LANG_TSWANA:     case LANG_VENDA:
@@ -549,7 +548,6 @@
     nOffset = 16;
     pnLookup = Lookup_16;
     break;
-#endif /* __REACTOS__ */
   case LANG_CZECH:  case LANG_HUNGARIAN:  case LANG_POLISH:
   case LANG_SLOVAK: case LANG_SPANISH:
     nOffset = 32;

reactos/lib/oleaut32
oaidl_p.c 1.2 -> 1.3
diff -u -r1.2 -r1.3
--- oaidl_p.c	1 Dec 2004 20:06:15 -0000	1.2
+++ oaidl_p.c	2 Dec 2004 19:38:49 -0000	1.3
@@ -28,6 +28,8 @@
 
 #include <stdarg.h>
 
+#define COBJMACROS
+
 #include "windef.h"
 #include "winbase.h"
 #include "objbase.h"

reactos/lib/oleaut32
oleaut.c 1.4 -> 1.5
diff -u -r1.4 -r1.5
--- oleaut.c	1 Mar 2004 22:45:23 -0000	1.4
+++ oleaut.c	2 Dec 2004 19:38:49 -0000	1.5
@@ -21,6 +21,8 @@
 #include <stdarg.h>
 #include <string.h>
 
+#define COBJMACROS
+
 #include "windef.h"
 #include "winbase.h"
 #include "wingdi.h"
@@ -47,7 +49,6 @@
 
 HMODULE OLEAUT32_hModule = NULL;
 
-
 /******************************************************************************
  * BSTR  {OLEAUT32}
  *
@@ -570,6 +571,28 @@
 }
 
 /******************************************************************************
+ *      GetRecordInfoFromGuids  [OLEAUT32.322]
+ *
+ * RETURNS
+ *  Success: S_OK
+ *  Failure: E_INVALIDARG, if any argument is invalid.
+ *
+ * BUGS
+ *  Unimplemented
+ */
+HRESULT WINAPI GetRecordInfoFromGuids(
+    REFGUID rGuidTypeLib,
+    ULONG uVerMajor,
+    ULONG uVerMinor,
+    LCID lcid,
+    REFGUID rGuidTypeInfo,
+    IRecordInfo** ppRecInfo)
+{
+    FIXME("(%p,%ld,%ld,%ld,%p,%p),stub!\n",rGuidTypeLib, uVerMajor, uVerMinor, lcid, rGuidTypeInfo, ppRecInfo);
+    return E_NOTIMPL;
+}
+
+/******************************************************************************
  *		OleTranslateColor	[OLEAUT32.421]
  *
  * Convert an OLE_COLOR to a COLORREF.
@@ -644,7 +667,7 @@
       /*
        * Validate GetSysColor index.
        */
-      if ((index < COLOR_SCROLLBAR) || (index > COLOR_GRADIENTINACTIVECAPTION))
+      if ((index < COLOR_SCROLLBAR) || (index > COLOR_MENUBAR))
         return E_INVALIDARG;
 
       *pColorRef =  GetSysColor(index);
@@ -667,7 +690,6 @@
 /***********************************************************************
  *		DllGetClassObject (OLEAUT32.1)
  */
-#ifndef __REACTOS__ /*FIXME: no marshalling yet*/
 HRESULT WINAPI OLEAUT32_DllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv)
 {
     *ppv = NULL;
@@ -696,7 +718,6 @@
     FIXME("\n\tCLSID:\t%s,\n\tIID:\t%s\n",debugstr_guid(rclsid),debugstr_guid(iid));
     return CLASS_E_CLASSNOTAVAILABLE;
 }
-#endif
 
 /***********************************************************************
  *		DllCanUnloadNow (OLEAUT32.410)
@@ -709,7 +730,7 @@
  * RETURNS
  *  Always returns S_FALSE. This dll cannot be unloaded.
  */
-HRESULT WINAPI OLEAUT32_DllCanUnloadNow()
+HRESULT WINAPI OLEAUT32_DllCanUnloadNow(void)
 {
     return S_FALSE;
 }

reactos/lib/oleaut32
oleaut32.rc 1.5 -> 1.6
diff -u -r1.5 -r1.6
--- oleaut32.rc	16 Oct 2004 20:27:36 -0000	1.5
+++ oleaut32.rc	2 Dec 2004 19:38:49 -0000	1.6
@@ -34,13 +34,14 @@
 #include "oleaut32_It.rc"
 #include "oleaut32_Nl.rc"
 #include "oleaut32_No.rc"
+#include "oleaut32_Pl.rc"
 #include "oleaut32_Pt.rc"
 #include "oleaut32_Sv.rc"
 #include "oleaut32_Th.rc"
 
 /*
  * FIXME:
- *  Polish, Finnish, Greek, Hebrew, Japanese, Korean, Portuguese,
+ *  Finnish, Greek, Hebrew, Japanese, Korean, Portuguese,
  *  Russian, Turkish, Slovenian (at least) are localised in XP Home.
  *  I expect Chinese etc are localised in Asian Editions also.
  */

reactos/lib/oleaut32
oleaut32.spec 1.8 -> 1.9
diff -u -r1.8 -r1.9
--- oleaut32.spec	1 Mar 2004 22:57:20 -0000	1.8
+++ oleaut32.spec	2 Dec 2004 19:38:49 -0000	1.9
@@ -1,4 +1,4 @@
-#1 stdcall -private DllGetClassObject(ptr ptr ptr) OLEAUT32_DllGetClassObject
+1 stdcall -private DllGetClassObject(ptr ptr ptr) OLEAUT32_DllGetClassObject
 2 stdcall SysAllocString(wstr)
 3 stdcall SysReAllocString(ptr wstr)
 4 stdcall SysAllocStringLen(wstr long)
@@ -142,12 +142,12 @@
 142 stdcall VarAnd(ptr ptr ptr)
 143 stdcall VarDiv(ptr ptr ptr)
 144 stub OACreateTypeLib2
-#146 stdcall DispCallFunc(ptr long long long long ptr ptr ptr)
+146 stdcall DispCallFunc(ptr long long long long ptr ptr ptr)
 147 stdcall VariantChangeTypeEx(ptr ptr long long long)
 148 stdcall SafeArrayPtrOfIndex(ptr ptr ptr)
 149 stdcall SysStringByteLen(ptr)
 150 stdcall SysAllocStringByteLen(ptr long)
-152 stub VarEqv # stdcall (ptr ptr ptr)
+152 stdcall VarEqv(ptr ptr ptr)
 153 stub VarIdiv # stdcall (ptr ptr ptr)
 154 stub VarImp # stdcall (ptr ptr ptr)
 155 stdcall VarMod(ptr ptr ptr)
@@ -155,18 +155,18 @@
 157 stdcall VarOr(ptr ptr ptr)
 158 stdcall VarPow(ptr ptr ptr)
 159 stdcall VarSub(ptr ptr ptr)
-#160 stdcall CreateTypeLib(long wstr ptr)
-#161 stdcall LoadTypeLib (wstr ptr)
-#162 stdcall LoadRegTypeLib (ptr long long long ptr)
-#163 stdcall RegisterTypeLib(ptr wstr wstr)
-#164 stdcall QueryPathOfRegTypeLib(ptr long long long ptr)
+160 stdcall CreateTypeLib(long wstr ptr)
+161 stdcall LoadTypeLib (wstr ptr)
+162 stdcall LoadRegTypeLib (ptr long long long ptr)
+163 stdcall RegisterTypeLib(ptr wstr wstr)
+164 stdcall QueryPathOfRegTypeLib(ptr long long long ptr)
 165 stdcall LHashValOfNameSys(long long wstr)
 166 stdcall LHashValOfNameSysA(long long str)
-167 stub VarXor # stdcall (ptr ptr ptr)
+167 stdcall VarXor(ptr ptr ptr)
 168 stdcall VarAbs(ptr ptr)
 169 stdcall VarFix(ptr ptr)
 170 stdcall OaBuildVersion()
-171 stub ClearCustData
+171 stdcall ClearCustData(ptr)
 172 stdcall VarInt(ptr ptr)
 173 stdcall VarNeg(ptr ptr)
 174 stdcall VarNot(ptr ptr)
@@ -175,13 +175,13 @@
 177 stdcall VarDecAdd(ptr ptr ptr)
 178 stdcall VarDecDiv(ptr ptr ptr)
 179 stdcall VarDecMul(ptr ptr ptr)
-#180 stdcall CreateTypeLib2(long wstr ptr)
+180 stdcall CreateTypeLib2(long wstr ptr)
 181 stdcall VarDecSub(ptr ptr ptr)
 182 stdcall VarDecAbs(ptr ptr)
-#183 stdcall LoadTypeLibEx (wstr long ptr)
+183 stdcall LoadTypeLibEx (wstr long ptr)
 184 stdcall SystemTimeToVariantTime(ptr ptr)
 185 stdcall VariantTimeToSystemTime(double ptr)
-#186 stdcall UnRegisterTypeLib (ptr long long long long)
+186 stdcall UnRegisterTypeLib (ptr long long long long)
 187 stdcall VarDecFix(ptr ptr)
 188 stdcall VarDecInt(ptr ptr)
 189 stdcall VarDecNeg(ptr ptr)
@@ -278,14 +278,14 @@
 280 stdcall VarUI4FromI1(long ptr)
 281 stdcall VarUI4FromUI2(long ptr)
 282 stdcall VarUI4FromDec(ptr ptr)
-#283 stdcall BSTR_UserSize(ptr long ptr)
-#284 stdcall BSTR_UserMarshal(ptr ptr ptr)
-#285 stdcall BSTR_UserUnmarshal(ptr ptr ptr)
-#286 stdcall BSTR_UserFree(ptr ptr)
-#287 stdcall VARIANT_UserSize(ptr long ptr)
-#288 stdcall VARIANT_UserMarshal(ptr ptr ptr)
-#289 stdcall VARIANT_UserUnmarshal(ptr ptr ptr)
-#290 stdcall VARIANT_UserFree(ptr ptr)
+283 stdcall BSTR_UserSize(ptr long ptr)
+284 stdcall BSTR_UserMarshal(ptr ptr ptr)
+285 stdcall BSTR_UserUnmarshal(ptr ptr ptr)
+286 stdcall BSTR_UserFree(ptr ptr)
+287 stdcall VARIANT_UserSize(ptr long ptr)
+288 stdcall VARIANT_UserMarshal(ptr ptr ptr)
+289 stdcall VARIANT_UserUnmarshal(ptr ptr ptr)
+290 stdcall VARIANT_UserFree(ptr ptr)
 291 stub LPSAFEARRAY_UserSize
 292 stub LPSAFEARRAY_UserMarshal
 293 stub LPSAFEARRAY_UserUnmarshal
@@ -311,10 +311,10 @@
 316 stdcall VarR4CmpR8(long double)
 317 stdcall VarR8Round(double long ptr)
 318 stdcall VarCat(ptr ptr ptr)
-319 stub VarDateFromUdateEx # stdcall (ptr long long ptr)
-#320 stdcall -private DllRegisterServer() OLEAUT32_DllRegisterServer
-#321 stdcall -private DllUnregisterServer() OLEAUT32_DllUnregisterServer
-322 stub GetRecordInfoFromGuids # stdcall (ptr long long long ptr ptr)
+319 stdcall VarDateFromUdateEx(ptr long long ptr)
+320 stdcall -private DllRegisterServer() OLEAUT32_DllRegisterServer
+321 stdcall -private DllUnregisterServer() OLEAUT32_DllUnregisterServer
+322 stdcall GetRecordInfoFromGuids(ptr long long long ptr ptr)
 323 stub GetRecordInfoFromTypeInfo # stdcall (ptr ptr)
 325 stub SetVarConversionLocaleSetting
 326 stub GetVarConversionLocaleSetting
@@ -392,7 +392,7 @@
 417 stdcall OleCreatePropertyFrame(ptr long long ptr long ptr long ptr ptr long ptr)
 418 stdcall OleLoadPicture(ptr long long ptr ptr)
 419 stdcall OleCreatePictureIndirect(ptr ptr long ptr)
-#420 stdcall OleCreateFontIndirect(ptr ptr ptr)
+420 stdcall OleCreateFontIndirect(ptr ptr ptr)
 421 stdcall OleTranslateColor(long long long)
 422 stub OleLoadPictureFile
 423 stub OleSavePictureFile

reactos/lib/oleaut32
oleaut32_De.rc 1.1 -> 1.2
diff -u -r1.1 -r1.2
--- oleaut32_De.rc	7 Feb 2004 18:53:58 -0000	1.1
+++ oleaut32_De.rc	2 Dec 2004 19:38:49 -0000	1.2
@@ -25,7 +25,7 @@
   IDS_TRUE  "Wahr"
   IDS_FALSE "Falsch"
   IDS_YES   "Ja"
-  IDS_NO    "Nei"
+  IDS_NO    "Nein"
   IDS_ON    "Ein"
   IDS_OFF   "Aus"
 }

reactos/lib/oleaut32
olefont.c 1.2 -> 1.3
diff -u -r1.2 -r1.3
--- olefont.c	1 Dec 2004 20:06:15 -0000	1.2
+++ olefont.c	2 Dec 2004 19:38:49 -0000	1.3
@@ -101,7 +101,7 @@
 /*
  * 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
+ * There is a version to accommodate all of the VTables implemented
  * by this object.
  */
 #define _ICOM_THIS_From_IDispatch(class, name) class* this = (class*)(((char*)name)-sizeof(void*))
@@ -139,7 +139,7 @@
 static HRESULT      WINAPI OLEFontImpl_get_hFont(IFont* iface, HFONT* phfont);
 static HRESULT      WINAPI OLEFontImpl_Clone(IFont* iface, IFont** ppfont);
 static HRESULT      WINAPI OLEFontImpl_IsEqual(IFont* iface, IFont* pFontOther);
-static HRESULT      WINAPI OLEFontImpl_SetRatio(IFont* iface, long cyLogical, long cyHimetric);
+static HRESULT      WINAPI OLEFontImpl_SetRatio(IFont* iface, LONG cyLogical, LONG cyHimetric);
 static HRESULT      WINAPI OLEFontImpl_QueryTextMetrics(IFont* iface, TEXTMETRICOLE* ptm);
 static HRESULT      WINAPI OLEFontImpl_AddRefHfont(IFont* iface, HFONT hfont);
 static HRESULT      WINAPI OLEFontImpl_ReleaseHfont(IFont* iface, HFONT hfont);
@@ -1048,8 +1048,8 @@
  */
 static HRESULT WINAPI OLEFontImpl_SetRatio(
   IFont* iface,
-  long   cyLogical,
-  long   cyHimetric)
+  LONG   cyLogical,
+  LONG   cyHimetric)
 {
   OLEFontImpl *this = (OLEFontImpl *)iface;
   TRACE("(%p)->(%ld, %ld)\n", this, cyLogical, cyHimetric);
@@ -1210,7 +1210,7 @@
   HRESULT hres;
 
   _ICOM_THIS_From_IDispatch(OLEFontImpl, iface);
-  TRACE("(%p, iTInfo=%d, lcid=%04x, %p), unimplemented stub!\n", this, iTInfo, (int)lcid, ppTInfo);
+  TRACE("(%p, iTInfo=%d, lcid=%04x, %p)\n", this, iTInfo, (int)lcid, ppTInfo);
   if (iTInfo != 0)
     return E_FAIL;
   hres = LoadTypeLib(stdole32tlb, &tl);
@@ -1276,11 +1276,36 @@
       V_VT(pVarResult) = VT_BSTR;
       return OLEFontImpl_get_Name(this, &V_BSTR(pVarResult));
     case DISPATCH_PROPERTYPUT: {
-      BSTR name = V_BSTR(&pDispParams->rgvarg[0]);
-      if (V_VT(&pDispParams->rgvarg[0])!=VT_BSTR) {
-        FIXME("property put of Name, vt is not VT_BSTR but %d\n",V_VT(&pDispParams->rgvarg[0]));
-	return E_FAIL;
+      BSTR name;
+      BOOL freename;
+      
+      if (V_VT(&pDispParams->rgvarg[0]) == VT_DISPATCH) {
+        IFont *font;
+        HRESULT hr = S_OK;
+        
+        hr = IUnknown_QueryInterface(V_DISPATCH(&pDispParams->rgvarg[0]), &IID_IFont, (void **) &font);
+        if (FAILED(hr))
+        {
+            FIXME("dispatch value for name property is not an OleFont, returning hr=0x%lx\n", hr);
+            return hr;
+        }
+
+        hr = IFont_get_Name(font, &name); /* this allocates a new BSTR so free it later */
+        if (FAILED(hr)) return hr;
+
+        IUnknown_Release(font);
+        
+        freename = TRUE;
+      } else if (V_VT(&pDispParams->rgvarg[0]) == VT_BSTR) {
+        name = V_BSTR(&pDispParams->rgvarg[0]);
+        freename = FALSE;
+      } else {
+        FIXME("app is trying to set name property with a non BSTR, non dispatch value. returning E_FAIL\n");
+        return E_FAIL;
       }
+
+      TRACE("name is %s\n", debugstr_w(name));
+      
       if (!xthis->description.lpstrName)
 	xthis->description.lpstrName = HeapAlloc(GetProcessHeap(), 0, (lstrlenW(name)+1) * sizeof(WCHAR));
       else
@@ -1289,6 +1314,9 @@
       if (xthis->description.lpstrName==0)
 	return E_OUTOFMEMORY;
       strcpyW(xthis->description.lpstrName, name);
+
+      if (freename) SysFreeString(name);
+      
       return S_OK;
     }
     }

reactos/lib/oleaut32
olepicture.c 1.3 -> 1.4
diff -u -r1.3 -r1.4
--- olepicture.c	26 Sep 2004 14:34:22 -0000	1.3
+++ olepicture.c	2 Dec 2004 19:38:49 -0000	1.4
@@ -36,6 +36,7 @@
  */
 
 #include "config.h"
+#include "wine/port.h"
 
 #ifdef HAVE_UNISTD_H
 # include <unistd.h>
@@ -49,10 +50,18 @@
  */
 #ifdef HAVE_GIF_LIB_H
 # include <gif_lib.h>
+# ifndef SONAME_LIBUNGIF
+#  define SONAME_LIBUNGIF "libungif.so"
+# endif
+# ifndef SONAME_LIBGIF
+#  define SONAME_LIBGIF "libgif.so"
+# endif
 #endif
 
+#define COBJMACROS
 #define NONAMELESSUNION
 #define NONAMELESSSTRUCT
+
 #include "winerror.h"
 #include "windef.h"
 #include "winbase.h"
@@ -67,16 +76,17 @@
 #include "wine/wingdi16.h"
 #include "cursoricon.h"
 
-#ifdef HAVE_LIBJPEG
+#ifdef HAVE_JPEGLIB_H
 /* This is a hack, so jpeglib.h does not redefine INT32 and the like*/
 #define XMD_H
 #define UINT8 JPEG_UINT8
 #define UINT16 JPEG_UINT16
 #undef FAR
-#ifdef HAVE_JPEGLIB_H
 # include <jpeglib.h>
-#endif
 #undef UINT16
+#ifndef SONAME_LIBJPEG
+#define SONAME_LIBJPEG "libjpeg.so"
+#endif
 #endif
 
 WINE_DEFAULT_DEBUG_CHANNEL(ole);
@@ -118,9 +128,16 @@
     BOOL keepOrigFormat;
     HDC	hDCCur;
 
+  /* Bitmap transparency mask */
+    HBITMAP hbmMask;
+    COLORREF rgbTrans;
+
   /* data */
     void* data;
     int datalen;
+    BOOL bIsDirty;                  /* Set to TRUE if picture has changed */
+    unsigned int loadtime_magic;    /* If a length header was found, saves value */
+    unsigned int loadtime_format;   /* for PICTYPE_BITMAP only, keeps track of image format (GIF/BMP/JPEG) */
 } OLEPictureImpl;
 
 /*
@@ -212,6 +229,11 @@
   /* dunno about original value */
   newObject->keepOrigFormat = TRUE;
 
+  newObject->hbmMask = NULL;
+  newObject->loadtime_magic = 0xdeadbeef;
+  newObject->loadtime_format = 0;
+  newObject->bIsDirty = FALSE;
+
   if (pictDesc) {
       if(pictDesc->cbSizeofstruct != sizeof(PICTDESC)) {
 	  FIXME("struct size = %d\n", pictDesc->cbSizeofstruct);
@@ -388,9 +410,7 @@
 {
   OLEPictureImpl *This = (OLEPictureImpl *)iface;
   TRACE("(%p)->(ref=%ld)\n", This, This->ref);
-  This->ref++;
-
-  return This->ref;
+  return InterlockedIncrement(&This->ref);
 }
 
 /************************************************************************
@@ -402,24 +422,20 @@
       IPicture* iface)
 {
   OLEPictureImpl *This = (OLEPictureImpl *)iface;
+  ULONG ret;
   TRACE("(%p)->(ref=%ld)\n", This, This->ref);
 
   /*
    * Decrease the reference count on this object.
    */
-  This->ref--;
+  ret = InterlockedDecrement(&This->ref);
 
   /*
    * If the reference count goes down to 0, perform suicide.
    */
-  if (This->ref==0)
-  {
-    OLEPictureImpl_Destroy(This);
+  if (ret==0) OLEPictureImpl_Destroy(This);
 
-    return 0;
-  }
-
-  return This->ref;
+  return ret;
 }
 
 
@@ -503,7 +519,7 @@
  * OLEPictureImpl_Render
  */
 static HRESULT WINAPI OLEPictureImpl_Render(IPicture *iface, HDC hdc,
-					    long x, long y, long cx, long cy,
+					    LONG x, LONG y, LONG cx, LONG cy,
 					    OLE_XPOS_HIMETRIC xSrc,
 					    OLE_YPOS_HIMETRIC ySrc,
 					    OLE_XSIZE_HIMETRIC cxSrc,
@@ -541,7 +557,25 @@
 
       hbmpOld = SelectObject(hdcBmp, This->desc.u.bmp.hbitmap);
 
-      StretchBlt(hdc, x, y, cx, cy, hdcBmp, xSrc, ySrc, cxSrc, cySrc, SRCCOPY);
+      if (This->hbmMask) {
+	  HDC hdcMask = CreateCompatibleDC(0);
+	  HBITMAP hOldbm = SelectObject(hdcMask, This->hbmMask);
+
+	  SetMapMode(hdcMask, MM_ANISOTROPIC);
+	  SetWindowOrgEx(hdcMask, 0, 0, NULL);
+	  SetWindowExtEx(hdcMask, This->himetricWidth, This->himetricHeight, NULL);
+	  SetViewportOrgEx(hdcMask, 0, This->origHeight, NULL);
+	  SetViewportExtEx(hdcMask, This->origWidth, -This->origHeight, NULL);
+	  
+	  SetBkColor(hdc, RGB(255, 255, 255));    
+	  SetTextColor(hdc, RGB(0, 0, 0));        
+	  StretchBlt(hdc, x, y, cx, cy, hdcMask, xSrc, ySrc, cxSrc, cySrc, SRCAND); 
+	  StretchBlt(hdc, x, y, cx, cy, hdcBmp, xSrc, ySrc, cxSrc, cySrc, SRCPAINT);
+
+	  SelectObject(hdcMask, hOldbm);
+	  DeleteDC(hdcMask);
+      } else
+	  StretchBlt(hdc, x, y, cx, cy, hdcBmp, xSrc, ySrc, cxSrc, cySrc, SRCCOPY);
 
       SelectObject(hdcBmp, hbmpOld);
       DeleteDC(hdcBmp);
@@ -645,6 +679,7 @@
   OLEPictureImpl *This = (OLEPictureImpl *)iface;
   TRACE("(%p)->()\n", This);
   OLEPicture_SendNotify(This,DISPID_PICT_HANDLE);
+  This->bIsDirty = TRUE;
   return S_OK;
 }
 
@@ -787,7 +822,7 @@
 {
   ICOM_THIS_From_IPersistStream(IPicture, iface);
   FIXME("(%p),stub!\n",This);
-  return E_NOTIMPL;
+  return E_FAIL;
 }
 
 /************************************************************************
@@ -801,7 +836,41 @@
   return E_NOTIMPL;
 }
 
-#ifdef HAVE_LIBJPEG
+#ifdef HAVE_JPEGLIB_H
+
+static void *libjpeg_handle;
+#define MAKE_FUNCPTR(f) static typeof(f) * p##f
+MAKE_FUNCPTR(jpeg_std_error);
+MAKE_FUNCPTR(jpeg_CreateDecompress);
+MAKE_FUNCPTR(jpeg_read_header);
+MAKE_FUNCPTR(jpeg_start_decompress);
+MAKE_FUNCPTR(jpeg_read_scanlines);
+MAKE_FUNCPTR(jpeg_finish_decompress);
+MAKE_FUNCPTR(jpeg_destroy_decompress);
+#undef MAKE_FUNCPTR
+
+static void *load_libjpeg(void)
+{
+    if((libjpeg_handle = wine_dlopen(SONAME_LIBJPEG, RTLD_NOW, NULL, 0)) != NULL) {
+
+#define LOAD_FUNCPTR(f) \
+    if((p##f = wine_dlsym(libjpeg_handle, #f, NULL, 0)) == NULL) { \
+        libjpeg_handle = NULL; \
+        return NULL; \
+    }
+
+        LOAD_FUNCPTR(jpeg_std_error);
+        LOAD_FUNCPTR(jpeg_CreateDecompress);
+        LOAD_FUNCPTR(jpeg_read_header);
+        LOAD_FUNCPTR(jpeg_start_decompress);
+        LOAD_FUNCPTR(jpeg_read_scanlines);
+        LOAD_FUNCPTR(jpeg_finish_decompress);
+        LOAD_FUNCPTR(jpeg_destroy_decompress);
+#undef LOAD_FUNCPTR
+    }
+    return libjpeg_handle;
+}
+
 /* for the jpeg decompressor source manager. */
 static void _jpeg_init_source(j_decompress_ptr cinfo) { }
 
@@ -821,15 +890,43 @@
     return FALSE;
 }
 static void _jpeg_term_source(j_decompress_ptr cinfo) { }
-#endif /* HAVE_LIBJPEG */
+#endif /* HAVE_JPEGLIB_H */
+
+#ifdef HAVE_GIF_LIB_H
+
+static void *libungif_handle;
+#define MAKE_FUNCPTR(f) static typeof(f) * p##f
+MAKE_FUNCPTR(DGifOpen);
+MAKE_FUNCPTR(DGifSlurp);
+MAKE_FUNCPTR(DGifCloseFile);
+#undef MAKE_FUNCPTR
 
-#ifdef HAVE_LIBGIF
 struct gifdata {
     unsigned char *data;
     unsigned int curoff;
     unsigned int len;
 };
 
+static void *load_libungif(void)
+{
+    if(((libungif_handle = wine_dlopen(SONAME_LIBUNGIF, RTLD_NOW, NULL, 0)) != NULL) ||
+       ((libungif_handle = wine_dlopen(SONAME_LIBGIF  , RTLD_NOW, NULL, 0)) != NULL)
+    ) {
+
+#define LOAD_FUNCPTR(f) \
+    if((p##f = wine_dlsym(libungif_handle, #f, NULL, 0)) == NULL) { \
+        libungif_handle = NULL; \
+        return NULL; \
+    }
+
+        LOAD_FUNCPTR(DGifOpen);
+        LOAD_FUNCPTR(DGifSlurp);
+        LOAD_FUNCPTR(DGifCloseFile);
+#undef LOAD_FUNCPTR
+    }
+    return libungif_handle;
+}
+
 static int _gif_inputfunc(GifFileType *gif, GifByteType *data, int len) {
     struct gifdata *gd = (struct gifdata*)gif->UserData;
 
@@ -841,7 +938,8 @@
     gd->curoff += len;
     return len;
 }
-#endif
+
+#endif  /* HAVE_GIF_LIB_H */
 
 /************************************************************************
  * OLEPictureImpl_IPersistStream_Load (IUnknown)
@@ -851,7 +949,7 @@
  * 	DWORD magic;
  * 	DWORD len;
  *
- * Currently implemented: BITMAP, ICON, JPEG.
+ * Currently implemented: BITMAP, ICON, JPEG, GIF
  */
 static HRESULT WINAPI OLEPictureImpl_Load(IPersistStream* iface,IStream*pStm) {
   HRESULT	hr = E_FAIL;
@@ -866,6 +964,13 @@
 
   /* Sometimes we have a header, sometimes we don't. Apply some guesses to find
    * out whether we do.
+   *
+   * UPDATE: the IStream can be mapped to a plain file instead of a stream in a
+   * compound file. This may explain most, if not all, of the cases of "no header",
+   * and the header validation should take this into account. At least in Visual Basic 6,
+   * resource streams, valid headers are
+   *    header[0] == "lt\0\0",
+   *    header[1] == length_of_stream.
    */
   hr=IStream_Stat(pStm,&statstg,STATFLAG_NONAME);
   if (hr)
@@ -875,7 +980,10 @@
       FIXME("Failure while reading picture header (hr is %lx, nread is %ld).\n",hr,xread);
       return hr;
   }
-  if (header[1] > statstg.cbSize.QuadPart || (header[1]==0)) {/* Incorrect header, assume none. */
+  if (!memcmp(&(header[0]), "GIF8",     4) ||   /* GIF header */
+      !memcmp(&(header[0]), "BM",       2) ||   /* BMP header */
+      !memcmp(&(header[0]), "\xff\xd8", 2) ||   /* JPEG header */
+      header[1] > statstg.cbSize.QuadPart || (header[1]==0)) {/* Incorrect header, assume none. */
     xread = 8;
     xbuf = This->data = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,statstg.cbSize.QuadPart);
     memcpy(xbuf,&header,8);
@@ -906,7 +1014,7 @@
   magic = xbuf[0] + (xbuf[1]<<8);
   switch (magic) {
   case 0x4947: { /* GIF */
-#ifdef HAVE_LIBGIF
+#ifdef HAVE_GIF_LIB_H
     struct gifdata 	gd;
     GifFileType 	*gif;
     BITMAPINFO		*bmi;
@@ -916,12 +1024,22 @@
     GifImageDesc        *gid;
     SavedImage          *si;
     ColorMapObject      *cm;
-    
+    int                 transparent = -1;
+    ExtensionBlock      *eb;
+    int                 padding;
+
+    if(!libungif_handle) {
+        if(!load_libungif()) {
+            FIXME("Failed reading GIF because unable to find %s/%s\n", SONAME_LIBUNGIF, SONAME_LIBGIF);
+            return E_FAIL;
+        }
+    }
+
     gd.data   = xbuf;
     gd.curoff = 0;
     gd.len    = xread;
-    gif = DGifOpen((void*)&gd, _gif_inputfunc);
-    ret = DGifSlurp(gif);
+    gif = pDGifOpen((void*)&gd, _gif_inputfunc);
+    ret = pDGifSlurp(gif);
     if (ret == GIF_ERROR) {
       FIXME("Failed reading GIF using libgif.\n");
       return E_FAIL;
@@ -939,28 +1057,69 @@
       gif->Image.Interlace
     );
     /* */
+    padding = (gif->SWidth+3) & ~3;
     bmi  = HeapAlloc(GetProcessHeap(),0,sizeof(BITMAPINFOHEADER)+(1<<gif->SColorResolution)*sizeof(RGBQUAD));
-    bytes= HeapAlloc(GetProcessHeap(),0,gif->SWidth*gif->SHeight);
+    bytes= HeapAlloc(GetProcessHeap(),0,padding*gif->SHeight);
     si   = gif->SavedImages+0;
     gid  = &(si->ImageDesc);
     cm   = gid->ColorMap;
     if (!cm) cm = gif->SColorMap;
+    
+    /* look for the transparent color extension */
+    for (i = 0; i < si->ExtensionBlockCount; ++i) {
+	eb = si->ExtensionBlocks + i;
+	if (eb->Function == 0xF9 && eb->ByteCount == 4) {
+	    if ((eb->Bytes[0] & 1) == 1) {
+		transparent = eb->Bytes[3];
+	    }
+	}
+    }
+
     for (i=0;i<(1<<gif->SColorResolution);i++) {
       bmi->bmiColors[i].rgbRed = cm->Colors[i].Red;
       bmi->bmiColors[i].rgbGreen = cm->Colors[i].Green;
       bmi->bmiColors[i].rgbBlue = cm->Colors[i].Blue;
+      if (i == transparent) {
+	  This->rgbTrans = RGB(bmi->bmiColors[i].rgbRed,
+			       bmi->bmiColors[i].rgbGreen,
+			       bmi->bmiColors[i].rgbBlue);
+      }
     }
+
     /* Map to in picture coordinates */
-    for (i=0;i<gid->Height;i++)
-      for (j=0;j<gid->Width;j++)
-        bytes[(gid->Top+i)*gif->SWidth+gid->Left+j]=si->RasterBits[i*gid->Width+j];
+    for (i = 0, j = 0; i < gid->Height; i++) {
+        if (gif->Image.Interlace) {
+            memcpy(
+                bytes + (gid->Top + j) * padding + gid->Left,
+                si->RasterBits + i * gid->Width,
+                gid->Width);
+
+            /* Lower bits of interlaced counter encode current interlace */
+            if (j & 1) j += 2;      /* Currently filling odd rows */
+            else if (j & 2) j += 4; /* Currently filling even rows not multiples of 4 */
+            else j += 8;            /* Currently filling every 8th row or 4th row in-between */
+
+            if (j >= gid->Height && i < gid->Height && (j & 1) == 0) {
+                /* End of current interlace, go to next interlace */
+                if (j & 2) j = 1;       /* Next iteration fills odd rows */
+                else if (j & 4) j = 2;  /* Next iteration fills even rows not mod 4 and not mod 8 */
+                else j = 4;             /* Next iteration fills rows in-between rows mod 6 */
+            }
+        } else {
+            memcpy(
+                bytes + (gid->Top + i) * padding + gid->Left,
+                si->RasterBits + i * gid->Width,
+                gid->Width);
+        }
+    }
+
     bmi->bmiHeader.biSize		= sizeof(BITMAPINFOHEADER);
     bmi->bmiHeader.biWidth		= gif->SWidth;
-    bmi->bmiHeader.biHeight		= gif->SHeight;
+    bmi->bmiHeader.biHeight		= -gif->SHeight;
     bmi->bmiHeader.biPlanes		= 1;
     bmi->bmiHeader.biBitCount		= 8;
     bmi->bmiHeader.biCompression	= BI_RGB;
-    bmi->bmiHeader.biSizeImage		= gif->SWidth*gif->SHeight;
+    bmi->bmiHeader.biSizeImage		= padding*gif->SHeight;
     bmi->bmiHeader.biXPelsPerMeter	= 0;
     bmi->bmiHeader.biYPelsPerMeter	= 0;
     bmi->bmiHeader.biClrUsed		= 1 << gif->SColorResolution;
@@ -973,12 +1132,40 @@
 	    CBM_INIT,
 	    bytes,
 	    bmi,
-	    DIB_PAL_COLORS
+	    DIB_RGB_COLORS
     );
+
+    if (transparent > -1) {
+	/* Create the Mask */
+	HDC hdc = CreateCompatibleDC(0);
+	HDC hdcMask = CreateCompatibleDC(0);
+	HBITMAP hOldbitmap; 
+	HBITMAP hOldbitmapmask;
+
+	This->hbmMask = CreateBitmap(bmi->bmiHeader.biWidth, bmi->bmiHeader.biHeight, 1, 1, NULL);
+
+	hOldbitmap = SelectObject(hdc,This->desc.u.bmp.hbitmap); 
+	hOldbitmapmask = SelectObject(hdcMask, This->hbmMask);
+	SetBkColor(hdc, This->rgbTrans);
+	BitBlt(hdcMask, 0, 0, bmi->bmiHeader.biWidth, bmi->bmiHeader.biHeight, hdc, 0, 0, SRCCOPY);
+
+	/* We no longer need the original bitmap, so we apply the first
+	   transformation with the mask to speed up the rendering */
+	SetBkColor(hdc, RGB(0,0,0));
+	SetTextColor(hdc, RGB(255,255,255));
+	BitBlt(hdc, 0, 0, bmi->bmiHeader.biWidth, bmi->bmiHeader.biHeight, 
+		 hdcMask, 0, 0,  SRCAND);
+
+	SelectObject(hdc, hOldbitmap);
+	SelectObject(hdcMask, hOldbitmapmask);
+	DeleteDC(hdcMask);
+	DeleteDC(hdc);
+    }
+    
     DeleteDC(hdcref);
     This->desc.picType = PICTYPE_BITMAP;
     OLEPictureImpl_SetBitmap(This);
-    DGifCloseFile(gif);
+    pDGifCloseFile(gif);
     HeapFree(GetProcessHeap(),0,bytes);
     return S_OK;
 #else
@@ -988,7 +1175,7 @@
     break;
   }
   case 0xd8ff: { /* JPEG */
-#ifdef HAVE_LIBJPEG
+#ifdef HAVE_JPEGLIB_H
     struct jpeg_decompress_struct	jd;
     struct jpeg_error_mgr		jerr;
     int					ret;
@@ -999,7 +1186,14 @@
     HDC					hdcref;
     struct jpeg_source_mgr		xjsm;
     LPBYTE                              oldbits;
-    int i;
+    unsigned int i;
+
+    if(!libjpeg_handle) {
+        if(!load_libjpeg()) {
+            FIXME("Failed reading JPEG because unable to find %s\n", SONAME_LIBJPEG);
+            return E_FAIL;
+        }
+    }
 
     /* This is basically so we can use in-memory data for jpeg decompression.
      * We need to have all the functions.
@@ -1012,12 +1206,14 @@
     xjsm.resync_to_restart	= _jpeg_resync_to_restart;
     xjsm.term_source		= _jpeg_term_source;
 
-    jd.err = jpeg_std_error(&jerr);
-    jpeg_create_decompress(&jd);
+    jd.err = pjpeg_std_error(&jerr);
+    /* jpeg_create_decompress is a macro that expands to jpeg_CreateDecompress - see jpeglib.h
+     * jpeg_create_decompress(&jd); */
+    pjpeg_CreateDecompress(&jd, JPEG_LIB_VERSION, (size_t) sizeof(struct jpeg_decompress_struct));
     jd.src = &xjsm;
-    ret=jpeg_read_header(&jd,TRUE);
+    ret=pjpeg_read_header(&jd,TRUE);
     jd.out_color_space = JCS_RGB;
-    jpeg_start_decompress(&jd);
+    pjpeg_start_decompress(&jd);
     if (ret != JPEG_HEADER_OK) {
 	ERR("Jpeg image in stream has bad format, read header returned %d.\n",ret);
 	HeapFree(GetProcessHeap(),0,xbuf);
@@ -1031,7 +1227,7 @@
     oldbits = bits;
     oldsamprow = samprow;
     while ( jd.output_scanline<jd.output_height ) {
-      x = jpeg_read_scanlines(&jd,&samprow,1);
+      x = pjpeg_read_scanlines(&jd,&samprow,1);
       if (x != 1) {
 	FIXME("failed to read current scanline?\n");
 	break;
@@ -1060,8 +1256,8 @@
     bmi.biClrImportant	= 0;
 
     HeapFree(GetProcessHeap(),0,samprow);
-    jpeg_finish_decompress(&jd);
-    jpeg_destroy_decompress(&jd);
+    pjpeg_finish_decompress(&jd);
+    pjpeg_destroy_decompress(&jd);
     hdcref = GetDC(0);
     This->desc.u.bmp.hbitmap=CreateDIBitmap(
 	    hdcref,
@@ -1097,7 +1293,7 @@
 	CBM_INIT,
 	xbuf+bfh->bfOffBits,
 	bi,
-	(bi->bmiHeader.biBitCount<=8)?DIB_PAL_COLORS:DIB_RGB_COLORS
+       DIB_RGB_COLORS
     );
     DeleteDC(hdcref);
     This->desc.picType = PICTYPE_BITMAP;
@@ -1108,6 +1304,7 @@
   case 0x0000: { /* ICON , first word is dwReserved */
     HICON hicon;
     CURSORICONFILEDIR	*cifd = (CURSORICONFILEDIR*)xbuf;
+    HDC hdcRef;
     int	i;
 
     /*
@@ -1153,15 +1350,19 @@
     } else {
 	This->desc.picType = PICTYPE_ICON;
 	This->desc.u.icon.hicon = hicon;
-	This->himetricWidth = cifd->idEntries[i].bWidth;
-	This->himetricHeight = cifd->idEntries[i].bHeight;
+	This->origWidth = cifd->idEntries[i].bWidth;
+	This->origHeight = cifd->idEntries[i].bHeight;
+	hdcRef = CreateCompatibleDC(0);
+	This->himetricWidth =(cifd->idEntries[i].bWidth *2540)/GetDeviceCaps(hdcRef, LOGPIXELSX);
+	This->himetricHeight=(cifd->idEntries[i].bHeight*2540)/GetDeviceCaps(hdcRef, LOGPIXELSY);
+	DeleteDC(hdcRef);
 	hr = S_OK;
     }
     break;
   }
   default:
   {
-    int i;
+    unsigned int i;
     FIXME("Unknown magic %04x, %ld read bytes:\n",magic,xread);
     hr=E_FAIL;
     for (i=0;i<xread+8;i++) {
@@ -1173,6 +1374,7 @@
     break;
   }
   }
+  This->bIsDirty = FALSE;
 
   /* FIXME: this notify is not really documented */
   if (hr==S_OK)
@@ -1180,12 +1382,324 @@
   return hr;
 }
 
+static int serializeIcon(HICON hIcon, void ** ppBuffer, unsigned int * pLength);
+static int serializeBMP(HBITMAP hBitmap, void ** ppBuffer, unsigned int * pLength);
 static HRESULT WINAPI OLEPictureImpl_Save(
   IPersistStream* iface,IStream*pStm,BOOL fClearDirty)
 {
-  ICOM_THIS_From_IPersistStream(IPicture, iface);
-  FIXME("(%p,%p,%d),stub!\n",This,pStm,fClearDirty);
-  return E_NOTIMPL;
+    HRESULT hResult = E_NOTIMPL;
+    void * pIconData;
+    unsigned int iDataSize;
+    ULONG dummy;
+    int iSerializeResult = 0;
+
+  ICOM_THIS_From_IPersistStream(OLEPictureImpl, iface);
+
+    switch (This->desc.picType) {
+    case PICTYPE_ICON:
+        if (This->bIsDirty) {
+            if (serializeIcon(This->desc.u.icon.hicon, &pIconData, &iDataSize)) {
+                if (This->loadtime_magic != 0xdeadbeef) {
+                    DWORD header[2];
+
+                    header[0] = This->loadtime_magic;
+                    header[1] = iDataSize;
+                    IStream_Write(pStm, header, 2 * sizeof(DWORD), &dummy);
+                }
+                IStream_Write(pStm, pIconData, iDataSize, &dummy);
+
+                HeapFree(GetProcessHeap(), 0, This->data);
+                This->data = pIconData;
+                This->datalen = iDataSize;
+                hResult = S_OK;
+            } else {
+                FIXME("(%p,%p,%d), unable to serializeIcon()!\n",This,pStm,fClearDirty);
+                hResult = E_FAIL;
+            }
+        } else {
+            if (This->loadtime_magic != 0xdeadbeef) {
+                DWORD header[2];
+
+                header[0] = This->loadtime_magic;
+                header[1] = This->datalen;
+                IStream_Write(pStm, header, 2 * sizeof(DWORD), &dummy);
+            }
+            IStream_Write(pStm, This->data, This->datalen, &dummy);
+            hResult = S_OK;
+        }
+        break;
+    case PICTYPE_BITMAP:
+        if (This->bIsDirty) {
+            switch (This->keepOrigFormat ? This->loadtime_format : 0x4d42) {
+            case 0x4d42:
+                iSerializeResult = serializeBMP(This->desc.u.bmp.hbitmap, &pIconData, &iDataSize);
+                break;
+            case 0xd8ff:
+                FIXME("(%p,%p,%d), PICTYPE_BITMAP (format JPEG) not implemented!\n",This,pStm,fClearDirty);
+                break;
+            case 0x4947:
+                FIXME("(%p,%p,%d), PICTYPE_BITMAP (format GIF) not implemented!\n",This,pStm,fClearDirty);
+                break;
+            default:
+                FIXME("(%p,%p,%d), PICTYPE_BITMAP (format UNKNOWN, using BMP?) not implemented!\n",This,pStm,fClearDirty);
+                break;
+            }
+            if (iSerializeResult) {
+                /*
+                if (This->loadtime_magic != 0xdeadbeef) {
+                */
+                if (1) {
+                    DWORD header[2];
+
+                    header[0] = (This->loadtime_magic != 0xdeadbeef) ? This->loadtime_magic : 0x0000746c;
+                    header[1] = iDataSize;
+                    IStream_Write(pStm, header, 2 * sizeof(DWORD), &dummy);
+                }
+                IStream_Write(pStm, pIconData, iDataSize, &dummy);
+
+                HeapFree(GetProcessHeap(), 0, This->data);
+                This->data = pIconData;
+                This->datalen = iDataSize;
+                hResult = S_OK;
+            }
+        } else {
+            /*
+            if (This->loadtime_magic != 0xdeadbeef) {
+            */
+            if (1) {
+                DWORD header[2];
+
+                header[0] = (This->loadtime_magic != 0xdeadbeef) ? This->loadtime_magic : 0x0000746c;
+                header[1] = This->datalen;
+                IStream_Write(pStm, header, 2 * sizeof(DWORD), &dummy);
+            }
+            IStream_Write(pStm, This->data, This->datalen, &dummy);
+            hResult = S_OK;
+        }
+        break;
+    case PICTYPE_METAFILE:
+        FIXME("(%p,%p,%d), PICTYPE_METAFILE not implemented!\n",This,pStm,fClearDirty);
+        break;
+    case PICTYPE_ENHMETAFILE:
+        FIXME("(%p,%p,%d),PICTYPE_ENHMETAFILE not implemented!\n",This,pStm,fClearDirty);
+        break;
+    default:
+        FIXME("(%p,%p,%d), [unknown type] not implemented!\n",This,pStm,fClearDirty);
+        break;
+    }
+    if (hResult == S_OK && fClearDirty) This->bIsDirty = FALSE;
+    return hResult;
+}
+
+static int serializeBMP(HBITMAP hBitmap, void ** ppBuffer, unsigned int * pLength)
+{
+    int iSuccess = 0;
+    HDC hDC;
+    BITMAPINFO * pInfoBitmap;
+    int iNumPaletteEntries;
+    unsigned char * pPixelData;
+    BITMAPFILEHEADER * pFileHeader;
+    BITMAPINFO * pInfoHeader;
+
+    pInfoBitmap = (BITMAPINFO *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
+        sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
+
+    /* Find out bitmap size and padded length */
+    hDC = GetDC(0);
+    pInfoBitmap->bmiHeader.biSize = sizeof(pInfoBitmap->bmiHeader);
+    GetDIBits(hDC, hBitmap, 0, 0, NULL, pInfoBitmap, DIB_RGB_COLORS);
+
+    /* Fetch bitmap palette & pixel data */
+
+    pPixelData = (unsigned char *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
+        pInfoBitmap->bmiHeader.biSizeImage);
+    GetDIBits(hDC, hBitmap, 0, pInfoBitmap->bmiHeader.biHeight, pPixelData, pInfoBitmap, DIB_RGB_COLORS);
+
+    /* Calculate the total length required for the BMP data */
+    if (pInfoBitmap->bmiHeader.biClrUsed != 0) iNumPaletteEntries = pInfoBitmap->bmiHeader.biClrUsed;
+    else if (pInfoBitmap->bmiHeader.biBitCount <= 8) iNumPaletteEntries = 1 << pInfoBitmap->bmiHeader.biBitCount;
+    else iNumPaletteEntries = 0;
+    *pLength =
+        sizeof(BITMAPFILEHEADER) +
+        sizeof(BITMAPINFOHEADER) +
+        iNumPaletteEntries * sizeof(RGBQUAD) +
+        pInfoBitmap->bmiHeader.biSizeImage;
+    *ppBuffer = (void *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, *pLength);
+
+    /* Fill the BITMAPFILEHEADER */
+    pFileHeader = (BITMAPFILEHEADER *)(*ppBuffer);
+    pFileHeader->bfType = 0x4d42;
+    pFileHeader->bfSize = *pLength;
+    pFileHeader->bfOffBits =
+        sizeof(BITMAPFILEHEADER) +
+        sizeof(BITMAPINFOHEADER) +
+        iNumPaletteEntries * sizeof(RGBQUAD);
+
+    /* Fill the BITMAPINFOHEADER and the palette data */
+    pInfoHeader = (BITMAPINFO *)((unsigned char *)(*ppBuffer) + sizeof(BITMAPFILEHEADER));
+    memcpy(pInfoHeader, pInfoBitmap, sizeof(BITMAPINFOHEADER) + iNumPaletteEntries * sizeof(RGBQUAD));
+    memcpy(
+        (unsigned char *)(*ppBuffer) +
+            sizeof(BITMAPFILEHEADER) +
+            sizeof(BITMAPINFOHEADER) +
+            iNumPaletteEntries * sizeof(RGBQUAD),
+        pPixelData, pInfoBitmap->bmiHeader.biSizeImage);
+    iSuccess = 1;
+
+    HeapFree(GetProcessHeap(), 0, pPixelData);
+    HeapFree(GetProcessHeap(), 0, pInfoBitmap);
+    return iSuccess;
+}
+
+static int serializeIcon(HICON hIcon, void ** ppBuffer, unsigned int * pLength)
+{
+	ICONINFO infoIcon;
+	int iSuccess = 0;
+
+	*ppBuffer = NULL; *pLength = 0;
+	if (GetIconInfo(hIcon, &infoIcon)) {
+		HDC hDC;
+		BITMAPINFO * pInfoBitmap;
+		unsigned char * pIconData = NULL;
+		unsigned int iDataSize = 0;
+
+        pInfoBitmap = (BITMAPINFO *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
+
+		/* Find out icon size */
+		hDC = GetDC(0);
+		pInfoBitmap->bmiHeader.biSize = sizeof(pInfoBitmap->bmiHeader);
+		GetDIBits(hDC, infoIcon.hbmColor, 0, 0, NULL, pInfoBitmap, DIB_RGB_COLORS);
+		if (1) {
+			/* Auxiliary pointers */
+			CURSORICONFILEDIR * pIconDir;
+			CURSORICONFILEDIRENTRY * pIconEntry;
+			BITMAPINFOHEADER * pIconBitmapHeader;
+			unsigned int iOffsetPalette;
+			unsigned int iOffsetColorData;
+			unsigned int iOffsetMaskData;
+
+			unsigned int iLengthScanLineColor;
+			unsigned int iLengthScanLineMask;
+			unsigned int iNumEntriesPalette;
+
+			iLengthScanLineMask = ((pInfoBitmap->bmiHeader.biWidth + 31) >> 5) << 2;
+			iLengthScanLineColor = ((pInfoBitmap->bmiHeader.biWidth * pInfoBitmap->bmiHeader.biBitCount + 31) >> 5) << 2;
+/*
+			FIXME("DEBUG: bitmap size is %d x %d\n",
+				pInfoBitmap->bmiHeader.biWidth,
+				pInfoBitmap->bmiHeader.biHeight);
+			FIXME("DEBUG: bitmap bpp is %d\n",
+				pInfoBitmap->bmiHeader.biBitCount);
+			FIXME("DEBUG: bitmap nplanes is %d\n",
+				pInfoBitmap->bmiHeader.biPlanes);
+			FIXME("DEBUG: bitmap biSizeImage is %lu\n",
+				pInfoBitmap->bmiHeader.biSizeImage);
+*/
+			/* Let's start with one CURSORICONFILEDIR and one CURSORICONFILEDIRENTRY */
+			iDataSize += 3 * sizeof(WORD) + sizeof(CURSORICONFILEDIRENTRY) + sizeof(BITMAPINFOHEADER);
+			pIconData = (unsigned char *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, iDataSize);
+
+			/* Fill out the CURSORICONFILEDIR */
+			pIconDir = (CURSORICONFILEDIR *)pIconData;
+			pIconDir->idType = 1;
+			pIconDir->idCount = 1;
+
+			/* Fill out the CURSORICONFILEDIRENTRY */
+			pIconEntry = (CURSORICONFILEDIRENTRY *)(pIconData + 3 * sizeof(WORD));
+			pIconEntry->bWidth = (unsigned char)pInfoBitmap->bmiHeader.biWidth;
+			pIconEntry->bHeight = (unsigned char)pInfoBitmap->bmiHeader.biHeight;
+			pIconEntry->bColorCount =
+				(pInfoBitmap->bmiHeader.biBitCount < 8)
+				? 1 << pInfoBitmap->bmiHeader.biBitCount
+				: 0;
+			pIconEntry->xHotspot = pInfoBitmap->bmiHeader.biPlanes;
+			pIconEntry->yHotspot = pInfoBitmap->bmiHeader.biBitCount;
+			pIconEntry->dwDIBSize = 0;
+			pIconEntry->dwDIBOffset = 3 * sizeof(WORD) + sizeof(CURSORICONFILEDIRENTRY);
+
+			/* Fill out the BITMAPINFOHEADER */
+			pIconBitmapHeader = (BITMAPINFOHEADER *)(pIconData + 3 * sizeof(WORD) + sizeof(CURSORICONFILEDIRENTRY));
+			memcpy(pIconBitmapHeader, &pInfoBitmap->bmiHeader, sizeof(BITMAPINFOHEADER));
+
+			/*	Find out whether a palette exists for the bitmap */
+			if (	(pInfoBitmap->bmiHeader.biBitCount == 16 && pInfoBitmap->bmiHeader.biCompression == BI_RGB)
+				||	(pInfoBitmap->bmiHeader.biBitCount == 24)
+				||	(pInfoBitmap->bmiHeader.biBitCount == 32 && pInfoBitmap->bmiHeader.biCompression == BI_RGB)) {
+				iNumEntriesPalette = pInfoBitmap->bmiHeader.biClrUsed;
+			} else if ((pInfoBitmap->bmiHeader.biBitCount == 16 || pInfoBitmap->bmiHeader.biBitCount == 32)
+				&& pInfoBitmap->bmiHeader.biCompression == BI_BITFIELDS) {
+				iNumEntriesPalette = 3;
+			} else if (pInfoBitmap->bmiHeader.biBitCount <= 8) {
+				iNumEntriesPalette = 1 << pInfoBitmap->bmiHeader.biBitCount;
+			} else {
+				iNumEntriesPalette = 0;
+			}
+
+			/*  Add bitmap size and header size to icon data size. */
+			iOffsetPalette = iDataSize;
+			iDataSize += iNumEntriesPalette * sizeof(DWORD);
+			iOffsetColorData = iDataSize;
+			iDataSize += pIconBitmapHeader->biSizeImage;
+			iOffsetMaskData = iDataSize;
+			iDataSize += pIconBitmapHeader->biHeight * iLengthScanLineMask;
+			pIconBitmapHeader->biSizeImage += pIconBitmapHeader->biHeight * iLengthScanLineMask;
+			pIconBitmapHeader->biHeight *= 2;
+			pIconData = (unsigned char *)HeapReAlloc(GetProcessHeap(), 0, pIconData, iDataSize);
+			pIconEntry = (CURSORICONFILEDIRENTRY *)(pIconData + 3 * sizeof(WORD));
+			pIconBitmapHeader = (BITMAPINFOHEADER *)(pIconData + 3 * sizeof(WORD) + sizeof(CURSORICONFILEDIRENTRY));
+			pIconEntry->dwDIBSize = iDataSize - (3 * sizeof(WORD) + sizeof(CURSORICONFILEDIRENTRY));
+
+			/* Get the actual bitmap data from the icon bitmap */
+			GetDIBits(hDC, infoIcon.hbmColor, 0, pInfoBitmap->bmiHeader.biHeight,
+				pIconData + iOffsetColorData, pInfoBitmap, DIB_RGB_COLORS);
+			if (iNumEntriesPalette > 0) {
+				memcpy(pIconData + iOffsetPalette, pInfoBitmap->bmiColors,
+					iNumEntriesPalette * sizeof(RGBQUAD));
+			}
+
+			/* Reset all values so that GetDIBits call succeeds */
+			memset(pIconData + iOffsetMaskData, 0, iDataSize - iOffsetMaskData);
+			memset(pInfoBitmap, 0, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
+			pInfoBitmap->bmiHeader.biSize = sizeof(pInfoBitmap->bmiHeader);
+/*
+            if (!(GetDIBits(hDC, infoIcon.hbmMask, 0, 0, NULL, pInfoBitmap, DIB_RGB_COLORS)
+				&& GetDIBits(hDC, infoIcon.hbmMask, 0, pIconEntry->bHeight,
+					pIconData + iOffsetMaskData, pInfoBitmap, DIB_RGB_COLORS))) {
+
+                printf("ERROR: unable to get bitmap mask (error %lu)\n",
+					GetLastError());
+
+			}
+*/
+            GetDIBits(hDC, infoIcon.hbmMask, 0, 0, NULL, pInfoBitmap, DIB_RGB_COLORS);
+            GetDIBits(hDC, infoIcon.hbmMask, 0, pIconEntry->bHeight, pIconData + iOffsetMaskData, pInfoBitmap, DIB_RGB_COLORS);
+
+			/* Write out everything produced so far to the stream */
+			*ppBuffer = pIconData; *pLength = iDataSize;
+			iSuccess = 1;
+		} else {
+/*
+			printf("ERROR: unable to get bitmap information via GetDIBits() (error %lu)\n",
+				GetLastError());
+*/
+		}
+		/*
+			Remarks (from MSDN entry on GetIconInfo):
+
+			GetIconInfo creates bitmaps for the hbmMask and hbmColor
+			members of ICONINFO. The calling application must manage
+			these bitmaps and delete them when they are no longer
+			necessary.
+		 */
+		if (hDC) ReleaseDC(0, hDC);
+		DeleteObject(infoIcon.hbmMask);
+		if (infoIcon.hbmColor) DeleteObject(infoIcon.hbmColor);
+		HeapFree(GetProcessHeap(), 0, pInfoBitmap);
+	} else {
+		printf("ERROR: Unable to get icon information (error %lu)\n",
+			GetLastError());
+	}
+	return iSuccess;
 }
 
 static HRESULT WINAPI OLEPictureImpl_GetSizeMax(
@@ -1493,13 +2007,13 @@
 static ULONG WINAPI
 SPCF_AddRef(LPCLASSFACTORY iface) {
 	IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
-	return ++(This->ref);
+	return InterlockedIncrement(&This->ref);
 }
 
 static ULONG WINAPI SPCF_Release(LPCLASSFACTORY iface) {
 	IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
 	/* static class, won't be  freed */
-	return --(This->ref);
+	return InterlockedDecrement(&This->ref);
 }
 
 static HRESULT WINAPI SPCF_CreateInstance(

reactos/lib/oleaut32
safearray.c 1.6 -> 1.7
diff -u -r1.6 -r1.7
--- safearray.c	1 Mar 2004 22:12:57 -0000	1.6
+++ safearray.c	2 Dec 2004 19:38:49 -0000	1.7
@@ -36,15 +36,16 @@
 #include <string.h>
 #include <stdarg.h>
 #include <stdio.h>
+
+#define COBJMACROS
+
 #include "windef.h"
 #include "winerror.h"
 #include "winbase.h"
-#include "oleauto.h"
-#include "wine/debug.h"
 #include "variant.h"
+#include "wine/debug.h"
 
-WINE_DEFAULT_DEBUG_CHANNEL(ole);
-
+WINE_DEFAULT_DEBUG_CHANNEL(variant);
 
 /************************************************************************
  * SafeArray {OLEAUT32}
@@ -61,8 +62,8 @@
  * using the IRecordInfo interface.
  *
  * There are two types of SafeArray, normal and vectors. Normal arrays can have
- * multiple dimensions and the data for the array is allocated seperately from
- * the array header. This is the most flexable type of array. Vectors, on the
+ * multiple dimensions and the data for the array is allocated separately from
+ * the array header. This is the most flexible type of array. Vectors, on the
  * other hand, are fixed in size and consist of a single allocated block, and a
  * single dimension.
  *
@@ -341,7 +342,9 @@
 
       while(ulCellCount--)
       {
-        VariantClear(lpVariant);
+        HRESULT hRet = VariantClear(lpVariant);
+
+        if (FAILED(hRet)) FIXME("VariantClear of element failed!\n");
         lpVariant++;
       }
     }
@@ -368,7 +371,10 @@
 
       while(ulCellCount--)
       {
-        VariantCopy(lpDest, lpVariant);
+        HRESULT hRet;
+
+        hRet = VariantCopy(lpDest, lpVariant);
+        if (FAILED(hRet)) FIXME("VariantCopy failed with 0x%lx\n", hRet);
         lpVariant++;
         lpDest++;
       }
@@ -873,8 +879,10 @@
         VARIANT* lpVariant = (VARIANT*)pvData;
         VARIANT* lpDest = (VARIANT*)lpvDest;
 
-        VariantClear(lpDest);
-        VariantCopy(lpDest, lpVariant);
+        hRet = VariantClear(lpDest);
+        if (FAILED(hRet)) FIXME("VariantClear failed with 0x%lx\n", hRet);
+        hRet = VariantCopy(lpDest, lpVariant);
+        if (FAILED(hRet)) FIXME("VariantCopy failed with 0x%lx\n", hRet);
       }
       else if (psa->fFeatures & FADF_BSTR)
       {
@@ -958,7 +966,10 @@
         VARIANT* lpVariant = (VARIANT*)lpvSrc;
         VARIANT* lpDest = (VARIANT*)pvData;
 
-        VariantCopy(lpDest, lpVariant);
+        /* The original content of pvData is ignored. */
+        V_VT(lpDest) = VT_EMPTY;
+        hRet = VariantCopy(lpDest, lpVariant);
+	if (FAILED(hRet)) FIXME("VariantCopy failed with 0x%lx\n", hRet);
       }
       else if (psa->fFeatures & FADF_BSTR)
       {
@@ -1241,9 +1252,10 @@
     return E_INVALIDARG;
 
   if (psa->cLocks)
-    return DISP_E_ARRAYISLOCKED; /* Cant delete a locked array */
+    return DISP_E_ARRAYISLOCKED; /* Can't delete a locked array */
 
-  if (psa->pvData)
+  /* If static, keep pvData and don't free */
+  if (psa->pvData && !(psa->fFeatures & FADF_STATIC))
   {
     /* Delete the actual item data */
     if (FAILED(SAFEARRAY_DestroyData(psa, 0)))

reactos/lib/oleaut32
tmarshal.c 1.3 -> 1.4
diff -u -r1.3 -r1.4
--- tmarshal.c	1 Dec 2004 20:06:15 -0000	1.3
+++ tmarshal.c	2 Dec 2004 19:38:49 -0000	1.4
@@ -30,8 +30,10 @@
 #include <stdio.h>
 #include <ctype.h>
 
+#define COBJMACROS
 #define NONAMELESSUNION
 #define NONAMELESSSTRUCT
+
 #include "winerror.h"
 #include "windef.h"
 #include "winbase.h"

reactos/lib/oleaut32
typelib.c 1.3 -> 1.4
diff -u -r1.3 -r1.4
--- typelib.c	1 Dec 2004 20:06:15 -0000	1.3
+++ typelib.c	2 Dec 2004 19:38:49 -0000	1.4
@@ -61,8 +61,10 @@
 #include <stdio.h>
 #include <ctype.h>
 
+#define COBJMACROS
 #define NONAMELESSUNION
 #define NONAMELESSSTRUCT
+
 #include "winerror.h"
 #include "windef.h"
 #include "winbase.h"
@@ -72,7 +74,6 @@
 
 #include "wine/unicode.h"
 #include "objbase.h"
-#include "heap.h"
 #include "ole2disp.h"
 #include "typelib.h"
 #include "wine/debug.h"
@@ -148,6 +149,50 @@
 #define FromLEDWords(X,Y) /*nothing*/
 #endif
 
+/* get the path of a typelib key, in the form "Typelib\\<guid>\\<maj>.<min>" */
+/* buffer must be at least 60 characters long */
+static WCHAR *get_typelib_key( REFGUID guid, WORD wMaj, WORD wMin, WCHAR *buffer )
+{
+    static const WCHAR TypelibW[] = {'T','y','p','e','l','i','b','\\',0};
+    static const WCHAR VersionFormatW[] = {'\\','%','u','.','%','u',0};
+
+    memcpy( buffer, TypelibW, sizeof(TypelibW) );
+    StringFromGUID2( guid, buffer + strlenW(buffer), 40 );
+    sprintfW( buffer + strlenW(buffer), VersionFormatW, wMaj, wMin );
+    return buffer;
+}
+
+/* get the path of an interface key, in the form "Interface\\<guid>" */
+/* buffer must be at least 50 characters long */
+static WCHAR *get_interface_key( REFGUID guid, WCHAR *buffer )
+{
+    static const WCHAR InterfaceW[] = {'I','n','t','e','r','f','a','c','e','\\',0};
+
+    memcpy( buffer, InterfaceW, sizeof(InterfaceW) );
+    StringFromGUID2( guid, buffer + strlenW(buffer), 40 );
+    return buffer;
+}
+
+/* get the lcid subkey for a typelib, in the form "<lcid>\\<syskind>" */
+/* buffer must be at least 16 characters long */
+static WCHAR *get_lcid_subkey( LCID lcid, SYSKIND syskind, WCHAR *buffer )
+{
+    static const WCHAR LcidFormatW[] = {'%','l','x','\\',0};
+    static const WCHAR win16W[] = {'w','i','n','1','6',0};
+    static const WCHAR win32W[] = {'w','i','n','3','2',0};
+
+    sprintfW( buffer, LcidFormatW, lcid );
+    switch(syskind)
+    {
+    case SYS_WIN16: strcatW( buffer, win16W ); break;
+    case SYS_WIN32: strcatW( buffer, win32W ); break;
+    default:
+        TRACE("Typelib is for unsupported syskind %i\n", syskind);
+        return NULL;
+    }
+    return buffer;
+}
+
 
 /****************************************************************************
  *		QueryPathOfRegTypeLib	[OLEAUT32.164]
@@ -162,40 +207,33 @@
 	LCID lcid,	/* [in] locale id */
 	LPBSTR path )	/* [out] path of typelib */
 {
-    /* don't need to ZeroMemory those arrays since sprintf and RegQueryValue add
-       string termination character on output strings */
-
-    HRESULT hr        = E_FAIL;
-
-    LCID    myLCID    = lcid;
-
-    char    szXGUID[80];
-    char    szTypeLibKey[100];
-    char    szPath[MAX_PATH];
-    DWORD   dwPathLen = sizeof(szPath);
+    HRESULT hr = E_FAIL;
+    LCID myLCID = lcid;
+    HKEY hkey;
+    WCHAR buffer[60];
+    WCHAR Path[MAX_PATH];
 
     if ( !HIWORD(guid) )
     {
-        sprintf(szXGUID,
-            "<guid 0x%08lx>",
-            (DWORD) guid);
+        FIXME("(guid %p,%d,%d,0x%04lx,%p),stub!\n", guid, wMaj, wMin, lcid, path);
+        return E_FAIL;
+    }
+
+    get_typelib_key( guid, wMaj, wMin, buffer );
 
-        FIXME("(%s,%d,%d,0x%04lx,%p),stub!\n", szXGUID, wMaj, wMin, (DWORD)lcid, path);
+    if (RegOpenKeyW( HKEY_CLASSES_ROOT, buffer, &hkey ) != ERROR_SUCCESS)
+    {
+        TRACE_(typelib)("%s not found\n", debugstr_w(buffer));
         return E_FAIL;
     }
 
     while (hr != S_OK)
     {
-        sprintf(szTypeLibKey,
-            "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[4], guid->Data4[5], guid->Data4[6], guid->Data4[7],
-            wMaj,
-            wMin,
-            myLCID);
+        DWORD dwPathLen = sizeof(Path);
+
+        get_lcid_subkey( myLCID, SYS_WIN32, buffer );
 
-        if (RegQueryValueA(HKEY_LOCAL_MACHINE, szTypeLibKey, szPath, &dwPathLen))
+        if (RegQueryValueW(hkey, buffer, Path, &dwPathLen))
         {
             if (!lcid)
                 break;
@@ -216,23 +254,11 @@
         }
         else
         {
-            DWORD len = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, szPath, dwPathLen, NULL, 0 );
-            BSTR bstrPath = SysAllocStringLen(NULL,len);
-
-            MultiByteToWideChar(CP_ACP,
-                                MB_PRECOMPOSED,
-                                szPath,
-                                dwPathLen,
-                                bstrPath,
-                                len);
-           *path = bstrPath;
-           hr = S_OK;
+            *path = SysAllocString( Path );
+            hr = S_OK;
         }
     }
-
-    if (hr != S_OK)
-		TRACE_(typelib)("%s not found\n", szTypeLibKey);
-
+    RegCloseKey( hkey );
     return hr;
 }
 
@@ -385,6 +411,13 @@
 }
 
 
+/* some string constants shared between RegisterTypeLib and UnRegisterTypeLib */
+static const WCHAR TypeLibW[] = {'T','y','p','e','L','i','b',0};
+static const WCHAR FLAGSW[] = {'F','L','A','G','S',0};
+static const WCHAR HELPDIRW[] = {'H','E','L','P','D','I','R',0};
+static const WCHAR ProxyStubClsidW[] = {'P','r','o','x','y','S','t','u','b','C','l','s','i','d',0};
+static const WCHAR ProxyStubClsid32W[] = {'P','r','o','x','y','S','t','u','b','C','l','s','i','d','3','2',0};
+
 /******************************************************************************
  *		RegisterTypeLib	[OLEAUT32.163]
  * Adds information about a type library to the System Registry
@@ -403,17 +436,17 @@
      OLECHAR * szHelpDir)  /* [in] dir to the helpfile for the library,
 							 may be NULL*/
 {
+    static const WCHAR PSOA[] = {'{','0','0','0','2','0','4','2','4','-',
+                                 '0','0','0','0','-','0','0','0','0','-','C','0','0','0','-',
+                                 '0','0','0','0','0','0','0','0','0','0','4','6','}',0};
     HRESULT res;
     TLIBATTR *attr;
-    OLECHAR guid[80];
-    LPSTR guidA;
-    CHAR keyName[120];
-    CHAR tmp[MAX_PATH];
+    WCHAR keyName[60];
+    WCHAR tmp[16];
     HKEY key, subKey;
     UINT types, tidx;
     TYPEKIND kind;
     DWORD disposition;
-    static const char *PSOA = "{00020424-0000-0000-C000-000000000046}";
 
     if (ptlib == NULL || szFullPath == NULL)
         return E_INVALIDARG;
@@ -421,14 +454,10 @@
     if (!SUCCEEDED(ITypeLib_GetLibAttr(ptlib, &attr)))
         return E_FAIL;
 
-    StringFromGUID2(&attr->guid, guid, 80);
-    guidA = HEAP_strdupWtoA(GetProcessHeap(), 0, guid);
-    snprintf(keyName, sizeof(keyName), "TypeLib\\%s\\%x.%x",
-        guidA, attr->wMajorVerNum, attr->wMinorVerNum);
-    HeapFree(GetProcessHeap(), 0, guidA);
+    get_typelib_key( &attr->guid, attr->wMajorVerNum, attr->wMinorVerNum, keyName );
 
     res = S_OK;
-    if (RegCreateKeyExA(HKEY_CLASSES_ROOT, keyName, 0, NULL, 0,
+    if (RegCreateKeyExW(HKEY_CLASSES_ROOT, keyName, 0, NULL, 0,
         KEY_WRITE, NULL, &key, NULL) == ERROR_SUCCESS)
     {
         LPOLESTR doc;
@@ -446,24 +475,10 @@
             res = E_FAIL;
 
         /* Make up the name of the typelib path subkey */
-        sprintf(tmp, "%lu\\", attr->lcid);
-        switch(attr->syskind) {
-        case SYS_WIN16:
-            strcat(tmp, "win16");
-            break;
-
-        case SYS_WIN32:
-            strcat(tmp, "win32");
-            break;
-
-        default:
-            TRACE("Typelib is for unsupported syskind %i\n", attr->syskind);
-            res = E_FAIL;
-            break;
-        }
+        if (!get_lcid_subkey( attr->lcid, attr->syskind, tmp )) res = E_FAIL;
 
         /* Create the typelib path subkey */
-        if (res == S_OK && RegCreateKeyExA(key, tmp, 0, NULL, 0,
+        if (res == S_OK && RegCreateKeyExW(key, tmp, 0, NULL, 0,
             KEY_WRITE, NULL, &subKey, NULL) == ERROR_SUCCESS)
         {
             if (RegSetValueExW(subKey, NULL, 0, REG_SZ,
@@ -476,14 +491,15 @@
             res = E_FAIL;
 
         /* Create the flags subkey */
-        if (res == S_OK && RegCreateKeyExA(key, "FLAGS", 0, NULL, 0,
+        if (res == S_OK && RegCreateKeyExW(key, FLAGSW, 0, NULL, 0,
             KEY_WRITE, NULL, &subKey, NULL) == ERROR_SUCCESS)
         {
-            CHAR buf[20];
             /* FIXME: is %u correct? */
-            snprintf(buf, sizeof(buf), "%u", attr->wLibFlags);
-            if (RegSetValueExA(subKey, NULL, 0, REG_SZ,
-                buf, lstrlenA(buf) + 1) != ERROR_SUCCESS)
+            static const WCHAR formatW[] = {'%','u',0};
+            WCHAR buf[20];
+            sprintfW(buf, formatW, attr->wLibFlags);
+            if (RegSetValueExW(subKey, NULL, 0, REG_SZ,
+                               (BYTE *)buf, (strlenW(buf) + 1)*sizeof(WCHAR) ) != ERROR_SUCCESS)
                 res = E_FAIL;
 
             RegCloseKey(subKey);
@@ -492,7 +508,7 @@
             res = E_FAIL;
 
         /* create the helpdir subkey */
-        if (res == S_OK && RegCreateKeyExA(key, "HELPDIR", 0, NULL, 0,
+        if (res == S_OK && RegCreateKeyExW(key, HELPDIRW, 0, NULL, 0,
             KEY_WRITE, NULL, &subKey, &disposition) == ERROR_SUCCESS)
         {
             BOOL freeHelpDir = FALSE;
@@ -598,41 +614,41 @@
                         }
 
 			/* register interface<->typelib coupling */
-			StringFromGUID2(&tattr->guid, guid, 80);
-			guidA = HEAP_strdupWtoA(GetProcessHeap(), 0, guid);
-			snprintf(keyName, sizeof(keyName), "Interface\\%s", guidA);
-			HeapFree(GetProcessHeap(), 0, guidA);
-
-			if (RegCreateKeyExA(HKEY_CLASSES_ROOT, keyName, 0, NULL, 0,
-					    KEY_WRITE, NULL, &key, NULL) == ERROR_SUCCESS) {
+			get_interface_key( &tattr->guid, keyName );
+			if (RegCreateKeyExW(HKEY_CLASSES_ROOT, keyName, 0, NULL, 0,
+					    KEY_WRITE, NULL, &key, NULL) == ERROR_SUCCESS)
+			{
 			    if (name)
 				RegSetValueExW(key, NULL, 0, REG_SZ,
-					       (BYTE *)name, lstrlenW(name) * sizeof(OLECHAR));
+					       (BYTE *)name, (strlenW(name)+1) * sizeof(OLECHAR));
 
-			    if (RegCreateKeyExA(key, "ProxyStubClsid", 0, NULL, 0,
+			    if (RegCreateKeyExW(key, ProxyStubClsidW, 0, NULL, 0,
 				KEY_WRITE, NULL, &subKey, NULL) == ERROR_SUCCESS) {
-				RegSetValueExA(subKey, NULL, 0, REG_SZ,
-					       PSOA, strlen(PSOA));
+				RegSetValueExW(subKey, NULL, 0, REG_SZ,
+					       (BYTE*)PSOA, sizeof PSOA);
 				RegCloseKey(subKey);
 			    }
 
-			    if (RegCreateKeyExA(key, "ProxyStubClsid32", 0, NULL, 0,
+			    if (RegCreateKeyExW(key, ProxyStubClsid32W, 0, NULL, 0,
 				KEY_WRITE, NULL, &subKey, NULL) == ERROR_SUCCESS) {
-				RegSetValueExA(subKey, NULL, 0, REG_SZ,
-					       PSOA, strlen(PSOA));
+				RegSetValueExW(subKey, NULL, 0, REG_SZ,
+					       (BYTE*)PSOA, sizeof PSOA);
 				RegCloseKey(subKey);
 			    }
 
-			    if (RegCreateKeyExA(key, "TypeLib", 0, NULL, 0,
-				KEY_WRITE, NULL, &subKey, NULL) == ERROR_SUCCESS) {
-				CHAR ver[32];
-				StringFromGUID2(&attr->guid, guid, 80);
-				snprintf(ver, sizeof(ver), "%x.%x",
-					 attr->wMajorVerNum, attr->wMinorVerNum);
+			    if (RegCreateKeyExW(key, TypeLibW, 0, NULL, 0,
+				KEY_WRITE, NULL, &subKey, NULL) == ERROR_SUCCESS)
+			    {
+				WCHAR buffer[40];
+				static const WCHAR fmtver[] = {'%','u','.','%','u',0 };
+				static const WCHAR VersionW[] = {'V','e','r','s','i','o','n',0};
+
+				StringFromGUID2(&attr->guid, buffer, 40);
 				RegSetValueExW(subKey, NULL, 0, REG_SZ,
-					       (BYTE *)guid, lstrlenW(guid) * sizeof(OLECHAR));
-				RegSetValueExA(subKey, "Version", 0, REG_SZ,
-					       ver, lstrlenA(ver));
+					       (BYTE *)buffer, (strlenW(buffer)+1) * sizeof(WCHAR));
+				sprintfW(buffer, fmtver, attr->wMajorVerNum, attr->wMinorVerNum);
+				RegSetValueExW(subKey, VersionW, 0, REG_SZ,
+					       (BYTE*)buffer, (strlenW(buffer)+1) * sizeof(WCHAR));
 				RegCloseKey(subKey);
 			    }
 
@@ -674,13 +690,10 @@
 {
     BSTR tlibPath = NULL;
     DWORD tmpLength;
-    CHAR keyName[MAX_PATH];
-    CHAR* syskindName;
-    CHAR subKeyName[MAX_PATH];
-    LPSTR guidA;
+    WCHAR keyName[60];
+    WCHAR subKeyName[50];
     int result = S_OK;
     DWORD i = 0;
-    OLECHAR guid[80];
     BOOL deleteOtherStuff;
     HKEY key = NULL;
     HKEY subKey = NULL;
@@ -693,23 +706,10 @@
     TRACE("(IID: %s): stub\n",debugstr_guid(libid));
 
     /* Create the path to the key */
-    StringFromGUID2(libid, guid, 80);
-    guidA = HEAP_strdupWtoA(GetProcessHeap(), 0, guid);
-    snprintf(keyName, sizeof(keyName), "TypeLib\\%s\\%x.%x",
-        guidA, wVerMajor, wVerMinor);
-    HeapFree(GetProcessHeap(), 0, guidA);
-
-    /* Work out the syskind name */
-    switch(syskind) {
-    case SYS_WIN16:
-        syskindName = "win16";
-        break;
+    get_typelib_key( libid, wVerMajor, wVerMinor, keyName );
 
-    case SYS_WIN32:
-        syskindName = "win32";
-        break;
-
-    default:
+    if (syskind != SYS_WIN16 && syskind != SYS_WIN32)
+    {
         TRACE("Unsupported syskind %i\n", syskind);
         result = E_INVALIDARG;
         goto end;
@@ -722,7 +722,7 @@
     }
 
     /* Try and open the key to the type library. */
-    if (RegOpenKeyExA(HKEY_CLASSES_ROOT, keyName, 0, KEY_READ | KEY_WRITE, &key) != S_OK) {
+    if (RegOpenKeyExW(HKEY_CLASSES_ROOT, keyName, 0, KEY_READ | KEY_WRITE, &key) != S_OK) {
         result = E_INVALIDARG;
         goto end;
     }
@@ -753,21 +753,18 @@
         }
 
         /* the path to the type */
-        StringFromGUID2(&typeAttr->guid, guid, 80);
-        guidA = HEAP_strdupWtoA(GetProcessHeap(), 0, guid);
-        snprintf(subKeyName, sizeof(subKeyName), "Interface\\%s", guidA);
-        HeapFree(GetProcessHeap(), 0, guidA);
+        get_interface_key( &typeAttr->guid, subKeyName );
 
         /* Delete its bits */
-        if (RegOpenKeyExA(HKEY_CLASSES_ROOT, subKeyName, 0, KEY_WRITE, &subKey) != S_OK) {
+        if (RegOpenKeyExW(HKEY_CLASSES_ROOT, subKeyName, 0, KEY_WRITE, &subKey) != S_OK) {
             goto enddeleteloop;
         }
-        RegDeleteKeyA(subKey, "ProxyStubClsid");
-        RegDeleteKeyA(subKey, "ProxyStubClsid32");
-        RegDeleteKeyA(subKey, "TypeLib");
+        RegDeleteKeyW(subKey, ProxyStubClsidW);
+        RegDeleteKeyW(subKey, ProxyStubClsid32W);
+        RegDeleteKeyW(subKey, TypeLibW);
         RegCloseKey(subKey);
         subKey = NULL;
-        RegDeleteKeyA(HKEY_CLASSES_ROOT, subKeyName);
+        RegDeleteKeyW(HKEY_CLASSES_ROOT, subKeyName);
 
 enddeleteloop:
         if (typeAttr) ITypeInfo_ReleaseTypeAttr(typeInfo, typeAttr);
@@ -777,40 +774,36 @@
     }
 
     /* Now, delete the type library path subkey */
-    sprintf(subKeyName, "%lu\\%s", lcid, syskindName);
-    RegDeleteKeyA(key, subKeyName);
-    sprintf(subKeyName, "%lu", lcid);
-    RegDeleteKeyA(key, subKeyName);
+    get_lcid_subkey( lcid, syskind, subKeyName );
+    RegDeleteKeyW(key, subKeyName);
+    *strrchrW( subKeyName, '\\' ) = 0;  /* remove last path component */
+    RegDeleteKeyW(key, subKeyName);
 
     /* check if there is anything besides the FLAGS/HELPDIR keys.
        If there is, we don't delete them */
-    tmpLength = sizeof(subKeyName);
+    tmpLength = sizeof(subKeyName)/sizeof(WCHAR);
     deleteOtherStuff = TRUE;
     i = 0;
-    while(RegEnumKeyExA(key, i++, subKeyName, &tmpLength, NULL, NULL, NULL, NULL) == S_OK) {
-        tmpLength = sizeof(subKeyName);
+    while(RegEnumKeyExW(key, i++, subKeyName, &tmpLength, NULL, NULL, NULL, NULL) == S_OK) {
+        tmpLength = sizeof(subKeyName)/sizeof(WCHAR);
 
         /* if its not FLAGS or HELPDIR, then we must keep the rest of the key */
-        if (!strcmp(subKeyName, "FLAGS")) continue;
-        if (!strcmp(subKeyName, "HELPDIR")) continue;
+        if (!strcmpW(subKeyName, FLAGSW)) continue;
+        if (!strcmpW(subKeyName, HELPDIRW)) continue;
         deleteOtherStuff = FALSE;
         break;
     }
 
     /* only delete the other parts of the key if we're absolutely sure */
     if (deleteOtherStuff) {
-        RegDeleteKeyA(key, "FLAGS");
-        RegDeleteKeyA(key, "HELPDIR");
+        RegDeleteKeyW(key, FLAGSW);
+        RegDeleteKeyW(key, HELPDIRW);
         RegCloseKey(key);
         key = NULL;
 
-        StringFromGUID2(libid, guid, 80);
-        guidA = HEAP_strdupWtoA(GetProcessHeap(), 0, guid);
-        sprintf(keyName, "TypeLib\\%s\\%x.%x", guidA, wVerMajor, wVerMinor);
-        RegDeleteKeyA(HKEY_CLASSES_ROOT, keyName);
-        sprintf(keyName, "TypeLib\\%s", guidA);
-        RegDeleteKeyA(HKEY_CLASSES_ROOT, keyName);
-        HeapFree(GetProcessHeap(), 0, guidA);
+        RegDeleteKeyW(HKEY_CLASSES_ROOT, keyName);
+        *strrchrW( keyName, '\\' ) = 0;  /* remove last path component */
+        RegDeleteKeyW(HKEY_CLASSES_ROOT, keyName);
     }
 
 end:
@@ -2167,7 +2160,7 @@
     hFile = CreateFileW( pszFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0 );
     if (INVALID_HANDLE_VALUE != hFile)
     {
-      HANDLE hMapping = CreateFileMappingA( hFile, NULL, PAGE_READONLY | SEC_COMMIT, 0, 0, NULL );
+      HANDLE hMapping = CreateFileMappingW( hFile, NULL, PAGE_READONLY | SEC_COMMIT, 0, 0, NULL );
       if (hMapping)
       {
         LPVOID pBase = MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0);
@@ -2200,8 +2193,8 @@
                                           LOAD_LIBRARY_AS_DATAFILE|LOAD_WITH_ALTERED_SEARCH_PATH);
       if (hinstDLL)
       {
-        HRSRC hrsrc = FindResourceA(hinstDLL, MAKEINTRESOURCEA(index),
-	  "TYPELIB");
+        static const WCHAR TYPELIBW[] = {'T','Y','P','E','L','I','B',0};
+        HRSRC hrsrc = FindResourceW(hinstDLL, MAKEINTRESOURCEW(index), TYPELIBW);
         if (hrsrc)
         {
           HGLOBAL hGlobal = LoadResource(hinstDLL, hrsrc);
@@ -3995,8 +3988,8 @@
 static HRESULT WINAPI ITypeLibComp_fnBind(
     ITypeComp * iface,
     OLECHAR * szName,
-    unsigned long lHash,
-    unsigned short wFlags,
+    ULONG lHash,
+    WORD wFlags,
     ITypeInfo ** ppTInfo,
     DESCKIND * pDescKind,
     BINDPTR * pBindPtr)
@@ -4008,7 +4001,7 @@
 static HRESULT WINAPI ITypeLibComp_fnBindType(
     ITypeComp * iface,
     OLECHAR * szName,
-    unsigned long lHash,
+    ULONG lHash,
     ITypeInfo ** ppTInfo,
     ITypeComp ** ppTComp)
 {
@@ -5739,6 +5732,75 @@
     ITypeInfo2_fnGetAllImplTypeCustData,
 };
 
+/******************************************************************************
+ * CreateDispTypeInfo [OLEAUT32.31]
+ *
+ * Build type information for an object so it can be called through an
+ * IDispatch interface.
+ *
+ * RETURNS
+ *  Success: S_OK. pptinfo contains the created ITypeInfo object.
+ *  Failure: E_INVALIDARG, if one or more arguments is invalid.
+ *
+ * NOTES
+ *  This call allows an objects methods to be accessed through IDispatch, by
+ *  building an ITypeInfo object that IDispatch can use to call through.
+ */
+HRESULT WINAPI CreateDispTypeInfo(
+	INTERFACEDATA *pidata, /* [I] Description of the interface to build type info for */
+	LCID lcid, /* [I] Locale Id */
+	ITypeInfo **pptinfo) /* [O] Destination for created ITypeInfo object */
+{
+    ITypeInfoImpl *pTIImpl;
+    int param, func;
+    TLBFuncDesc **ppFuncDesc;
+
+    pTIImpl = (ITypeInfoImpl*)ITypeInfo_Constructor();
+    pTIImpl->pTypeLib = NULL;
+    pTIImpl->index = 0;
+    pTIImpl->Name = NULL;
+    pTIImpl->dwHelpContext = -1;
+    memset(&pTIImpl->TypeAttr.guid, 0, sizeof(GUID));
+    pTIImpl->TypeAttr.lcid = lcid;
+    pTIImpl->TypeAttr.typekind = TKIND_COCLASS;
+    pTIImpl->TypeAttr.wMajorVerNum = 0;
+    pTIImpl->TypeAttr.wMinorVerNum = 0;
+    pTIImpl->TypeAttr.cbAlignment = 2;
+    pTIImpl->TypeAttr.cbSizeInstance = -1;
+    pTIImpl->TypeAttr.cbSizeVft = -1;
+    pTIImpl->TypeAttr.cFuncs = 0;
+    pTIImpl->TypeAttr.cImplTypes = 1;
+    pTIImpl->TypeAttr.cVars = 0;
+    pTIImpl->TypeAttr.wTypeFlags = 0;
+
+    ppFuncDesc = &pTIImpl->funclist;
+    for(func = 0; func < pidata->cMembers; func++) {
+        METHODDATA *md = pidata->pmethdata + func;
+        *ppFuncDesc = HeapAlloc(GetProcessHeap(), 0, sizeof(**ppFuncDesc));
+        (*ppFuncDesc)->Name = SysAllocString(md->szName);
+        (*ppFuncDesc)->funcdesc.memid = md->dispid;
+        (*ppFuncDesc)->funcdesc.invkind = md->wFlags;
+        (*ppFuncDesc)->funcdesc.callconv = md->cc;
+        (*ppFuncDesc)->funcdesc.cParams = md->cArgs;
+        (*ppFuncDesc)->funcdesc.cParamsOpt = 0;
+        (*ppFuncDesc)->funcdesc.oVft = md->iMeth;
+        (*ppFuncDesc)->funcdesc.wFuncFlags = 0; /*??*/
+        (*ppFuncDesc)->funcdesc.elemdescFunc.tdesc.vt = md->vtReturn;
+        (*ppFuncDesc)->funcdesc.lprgelemdescParam = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
+                                                              md->cArgs * sizeof(ELEMDESC));
+        (*ppFuncDesc)->pParamDesc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
+                                              md->cArgs * sizeof(TLBParDesc));
+        for(param = 0; param < md->cArgs; param++) {
+            (*ppFuncDesc)->funcdesc.lprgelemdescParam[param].tdesc.vt = md->ppdata[param].vt;
+            (*ppFuncDesc)->pParamDesc[param].Name = SysAllocString(md->ppdata[param].szName);
+        }
+        ppFuncDesc = &(*ppFuncDesc)->next;
+    }        
+    *pptinfo = (ITypeInfo*)pTIImpl;
+    return S_OK;
+
+}
+
 static HRESULT WINAPI ITypeComp_fnQueryInterface(ITypeComp * iface, REFIID riid, LPVOID * ppv)
 {
     ICOM_THIS_From_ITypeComp(ITypeInfoImpl, iface);
@@ -5763,8 +5825,8 @@
 static HRESULT WINAPI ITypeComp_fnBind(
     ITypeComp * iface,
     OLECHAR * szName,
-    unsigned long lHash,
-    unsigned short wFlags,
+    ULONG lHash,
+    WORD wFlags,
     ITypeInfo ** ppTInfo,
     DESCKIND * pDescKind,
     BINDPTR * pBindPtr)
@@ -5831,7 +5893,7 @@
 static HRESULT WINAPI ITypeComp_fnBindType(
     ITypeComp * iface,
     OLECHAR * szName,
-    unsigned long lHash,
+    ULONG lHash,
     ITypeInfo ** ppTInfo,
     ITypeComp ** ppTComp)
 {

reactos/lib/oleaut32
typelib2.c 1.3 -> 1.4
diff -u -r1.3 -r1.4
--- typelib2.c	1 Dec 2004 20:06:15 -0000	1.3
+++ typelib2.c	2 Dec 2004 19:38:49 -0000	1.4
@@ -35,8 +35,10 @@
 #include <stdio.h>
 #include <ctype.h>
 
+#define COBJMACROS
 #define NONAMELESSUNION
 #define NONAMELESSSTRUCT
+
 #include "winerror.h"
 #include "windef.h"
 #include "winbase.h"
@@ -46,7 +48,6 @@
 
 #include "wine/unicode.h"
 #include "objbase.h"
-#include "heap.h"
 #include "ole2disp.h"
 #include "typelib.h"
 #include "wine/debug.h"
@@ -270,7 +271,7 @@
 
     hash = 0;
     for (i = 0; i < 8; i ++) {
-	hash ^= ((short *)guid)[i];
+	hash ^= ((const short *)guid)[i];
     }
 
     return (hash & 0xf) | ((hash & 0x10) & (0 - !!(hash & 0xe0)));

reactos/lib/oleaut32
usrmarshal.c 1.1 -> 1.2
diff -u -r1.1 -r1.2
--- usrmarshal.c	7 Feb 2004 18:53:59 -0000	1.1
+++ usrmarshal.c	2 Dec 2004 19:38:49 -0000	1.2
@@ -22,8 +22,10 @@
 #include <stdarg.h>
 #include <string.h>
 
+#define COBJMACROS
 #define NONAMELESSUNION
 #define NONAMELESSSTRUCT
+
 #include "windef.h"
 #include "winbase.h"
 #include "wingdi.h"

reactos/lib/oleaut32
varformat.c 1.2 -> 1.3
diff -u -r1.2 -r1.3
--- varformat.c	28 Feb 2004 19:16:54 -0000	1.2
+++ varformat.c	2 Dec 2004 19:38:49 -0000	1.3
@@ -35,13 +35,12 @@
 #define NONAMELESSSTRUCT
 #include "windef.h"
 #include "winbase.h"
-#include "oleauto.h"
-#include "wine/debug.h"
 #include "wine/unicode.h"
 #include "winerror.h"
 #include "variant.h"
+#include "wine/debug.h"
 
-WINE_DEFAULT_DEBUG_CHANNEL(ole);
+WINE_DEFAULT_DEBUG_CHANNEL(variant);
 
 /* Make sure internal conversions to strings use the '.','+'/'-' and ','
  * format chars from the US locale. This enables us to parse the created
@@ -1387,7 +1386,7 @@
         TRACE("write %d fractional digits or skip\n", pToken[1]);
 
         for (count = 0; count < fractionalDigits; count++)
-          pBuff[count] = rgbDig[wholeNumberDigits + count];
+          pBuff[count] = '0' + rgbDig[wholeNumberDigits + count];
         pBuff += fractionalDigits;
       }
       else
@@ -1417,7 +1416,7 @@
         TRACE("write %d fractional digits or 0's\n", pToken[1]);
 
         for (count = 0; count < fractionalDigits; count++)
-          pBuff[count] = rgbDig[wholeNumberDigits + count];
+          pBuff[count] = '0' + rgbDig[wholeNumberDigits + count];
         pBuff += fractionalDigits;
         if (pToken[1] > fractionalDigits)
         {

reactos/lib/oleaut32
variant.c 1.10 -> 1.11
diff -u -r1.10 -r1.11
--- variant.c	2 Mar 2004 10:25:58 -0000	1.10
+++ variant.c	2 Dec 2004 19:38:49 -0000	1.11
@@ -28,17 +28,18 @@
 #include <stdlib.h>
 #include <stdarg.h>
 
+#define COBJMACROS
 #define NONAMELESSUNION
 #define NONAMELESSSTRUCT
+
 #include "windef.h"
 #include "winbase.h"
-#include "oleauto.h"
-#include "wine/debug.h"
 #include "wine/unicode.h"
 #include "winerror.h"
 #include "variant.h"
+#include "wine/debug.h"
 
-WINE_DEFAULT_DEBUG_CHANNEL(ole);
+WINE_DEFAULT_DEBUG_CHANNEL(variant);
 
 const char* wine_vtypes[VT_CLSID] =
 {
@@ -79,6 +80,7 @@
 {
   HRESULT res = DISP_E_TYPEMISMATCH;
   VARTYPE vtFrom =  V_TYPE(ps);
+  BOOL bIgnoreOverflow = FALSE;
   DWORD dwFlags = 0;
 
   TRACE("(%p->(%s%s),0x%08lx,0x%04x,%p->(%s%s),%s%s)\n", pd, debugstr_VT(pd),
@@ -113,7 +115,11 @@
   if (vtFrom == VT_INT)
     vtFrom = VT_I4;
   else if (vtFrom == VT_UINT)
-     vtFrom = VT_UI4;
+  {
+    vtFrom = VT_UI4;
+    if (vt == VT_I4)
+      bIgnoreOverflow = TRUE;
+  }
 
   if (vt == vtFrom)
      return VariantCopy(pd, ps);
@@ -193,7 +199,14 @@
     case VT_I2:       return VarI4FromI2(V_I2(ps), &V_I4(pd));
     case VT_UI1:      return VarI4FromUI1(V_UI1(ps), &V_I4(pd));
     case VT_UI2:      return VarI4FromUI2(V_UI2(ps), &V_I4(pd));
-    case VT_UI4:      return VarI4FromUI4(V_UI4(ps), &V_I4(pd));
+    case VT_UI4:      
+          if (bIgnoreOverflow)
+          {
+            V_VT(pd) = VT_I4;
+            V_I4(pd) = V_I4(ps);
+            return S_OK;
+          }
+          return VarI4FromUI4(V_UI4(ps), &V_I4(pd));
     case VT_I8:       return VarI4FromI8(V_I8(ps), &V_I4(pd));
     case VT_UI8:      return VarI4FromUI8(V_UI8(ps), &V_I4(pd));
     case VT_R4:       return VarI4FromR4(V_R4(ps), &V_I4(pd));
@@ -449,7 +462,6 @@
     case VT_DATE:     return VarCyFromDate(V_DATE(ps), &V_CY(pd));
     case VT_BOOL:     return VarCyFromBool(V_BOOL(ps), &V_CY(pd));
     case VT_DECIMAL:  return VarCyFromDec(&V_DECIMAL(ps), &V_CY(pd));
-
     case VT_DISPATCH: return VarCyFromDisp(V_DISPATCH(ps), lcid, &V_CY(pd));
     case VT_BSTR:     return VarCyFromStr(V_BSTR(ps), lcid, dwFlags, &V_CY(pd));
     }
@@ -608,7 +620,6 @@
         if (V_BSTR(pVarg))
           SysFreeString(V_BSTR(pVarg));
       }
-#ifndef __REACTOS__	/*FIXME: problems with MinGW and brecVal */
       else if (V_VT(pVarg) == VT_RECORD)
       {
         struct __tagBRECORD* pBr = &V_UNION(pVarg,brecVal);
@@ -618,7 +629,6 @@
           IRecordInfo_Release(pBr->pRecInfo);
         }
       }
-#endif
       else if (V_VT(pVarg) == VT_DISPATCH ||
                V_VT(pVarg) == VT_UNKNOWN)
       {
@@ -636,7 +646,6 @@
   return hres;
 }
 
-#ifndef __REACTOS__	/*FIXME: missing __tagBRECORD in MinGW */
 /******************************************************************************
  * Copy an IRecordInfo object contained in a variant.
  */
@@ -669,7 +678,6 @@
     hres = E_INVALIDARG;
   return hres;
 }
-#endif
 
 /******************************************************************************
  *    VariantCopy  [OLEAUT32.10]
@@ -735,12 +743,10 @@
 	  }
         }
       }
-#ifndef __REACTOS__	/*FIXME: missing __tagBRECORD in MinGW */
       else if (V_VT(pvargSrc) == VT_RECORD)
       {
         hres = VARIANT_CopyIRecordInfo(&V_UNION(pvargDest,brecVal));
       }
-#endif
       else if (V_VT(pvargSrc) == VT_DISPATCH ||
                V_VT(pvargSrc) == VT_UNKNOWN)
       {
@@ -862,13 +868,11 @@
     /* Native doesn't check that *V_BSTRREF(pSrc) is valid */
     V_BSTR(pvargDest) = SysAllocStringByteLen((char*)*V_BSTRREF(pSrc), SysStringByteLen(*V_BSTRREF(pSrc)));
   }
-#ifndef __REACTOS__	/*FIXME: missing __tagBRECORD in MinGW */
   else if (V_VT(pSrc) == (VT_RECORD|VT_BYREF))
   {
     V_UNION(pvargDest,brecVal) = V_UNION(pvargSrc,brecVal);
     hres = VARIANT_CopyIRecordInfo(&V_UNION(pvargDest,brecVal));
   }
-#endif
   else if (V_VT(pSrc) == (VT_DISPATCH|VT_BYREF) ||
            V_VT(pSrc) == (VT_UNKNOWN|VT_BYREF))
   {
@@ -978,26 +982,35 @@
 
       if (SUCCEEDED(res))
       {
-        VARIANTARG vTmp;
+        VARIANTARG vTmp, vSrcDeref;
 
-        V_VT(&vTmp) = VT_EMPTY;
-        res = VariantCopyInd(&vTmp, pvargSrc);
+        if(V_VT(pvargSrc)&VT_BYREF && !V_BYREF(pvargSrc))
+          res = DISP_E_TYPEMISMATCH;
+        else
+        {
+          V_VT(&vTmp) = VT_EMPTY;
+          V_VT(&vSrcDeref) = VT_EMPTY;
+          VariantClear(&vTmp);
+          VariantClear(&vSrcDeref);
+        }
 
         if (SUCCEEDED(res))
         {
-          res = VariantClear(pvargDest);
-
+          res = VariantCopyInd(&vSrcDeref, pvargSrc);
           if (SUCCEEDED(res))
           {
-            if (V_ISARRAY(&vTmp) || (vt & VT_ARRAY))
-              res = VARIANT_CoerceArray(pvargDest, &vTmp, vt);
+            if (V_ISARRAY(&vSrcDeref) || (vt & VT_ARRAY))
+              res = VARIANT_CoerceArray(&vTmp, &vSrcDeref, vt);
             else
-              res = VARIANT_Coerce(pvargDest, lcid, wFlags, &vTmp, vt);
+              res = VARIANT_Coerce(&vTmp, lcid, wFlags, &vSrcDeref, vt);
 
-            if (SUCCEEDED(res))
-              V_VT(pvargDest) = vt;
+            if (SUCCEEDED(res)) {
+                V_VT(&vTmp) = vt;
+                VariantCopy(pvargDest, &vTmp);
+            }
+            VariantClear(&vTmp);
+            VariantClear(&vSrcDeref);
           }
-          VariantClear(&vTmp);
         }
       }
     }
@@ -1289,12 +1302,13 @@
 }
 
 /***********************************************************************
- *              VarDateFromUdate [OLEAUT32.330]
+ *              VarDateFromUdateEx [OLEAUT32.319]
  *
  * Convert an unpacked format date and time to a variant VT_DATE.
  *
  * PARAMS
  *  pUdateIn [I] Unpacked format date and time to convert
+ *  lcid     [I] Locale identifier for the conversion
  *  dwFlags  [I] Flags controlling the conversion (VAR_ flags from "oleauto.h")
  *  pDateOut [O] Destination for variant VT_DATE.
  *
@@ -1302,17 +1316,20 @@
  *  Success: S_OK. *pDateOut contains the converted value.
  *  Failure: E_INVALIDARG, if pUdateIn cannot be represented in VT_DATE format.
  */
-HRESULT WINAPI VarDateFromUdate(UDATE *pUdateIn, ULONG dwFlags, DATE *pDateOut)
+HRESULT WINAPI VarDateFromUdateEx(UDATE *pUdateIn, LCID lcid, ULONG dwFlags, DATE *pDateOut)
 {
   UDATE ud;
   double dateVal;
 
-  TRACE("(%p->%d/%d/%d %d:%d:%d:%d %d %d,0x%08lx,%p)\n", pUdateIn,
+  TRACE("(%p->%d/%d/%d %d:%d:%d:%d %d %d,0x%08lx,0x%08lx,%p)\n", pUdateIn,
         pUdateIn->st.wMonth, pUdateIn->st.wDay, pUdateIn->st.wYear,
         pUdateIn->st.wHour, pUdateIn->st.wMinute, pUdateIn->st.wSecond,
         pUdateIn->st.wMilliseconds, pUdateIn->st.wDayOfWeek,
-        pUdateIn->wDayOfYear, dwFlags, pDateOut);
+        pUdateIn->wDayOfYear, lcid, dwFlags, pDateOut);
 
+  if (lcid != MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT))
+    FIXME("lcid possibly not handled, treating as en-us\n");
+      
   memcpy(&ud, pUdateIn, sizeof(ud));
 
   if (dwFlags & VAR_VALIDDATE)
@@ -1336,6 +1353,31 @@
 }
 
 /***********************************************************************
+ *              VarDateFromUdate [OLEAUT32.330]
+ *
+ * Convert an unpacked format date and time to a variant VT_DATE.
+ *
+ * PARAMS
+ *  pUdateIn [I] Unpacked format date and time to convert
+ *  dwFlags  [I] Flags controlling the conversion (VAR_ flags from "oleauto.h")
+ *  pDateOut [O] Destination for variant VT_DATE.
+ *
+ * RETURNS
+ *  Success: S_OK. *pDateOut contains the converted value.
+ *  Failure: E_INVALIDARG, if pUdateIn cannot be represented in VT_DATE format.
+ *
+ * NOTES
+ *  This function uses the United States English locale for the conversion. Use
+ *  VarDateFromUdateEx() for alternate locales.
+ */
+HRESULT WINAPI VarDateFromUdate(UDATE *pUdateIn, ULONG dwFlags, DATE *pDateOut)
+{
+  LCID lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
+  
+  return VarDateFromUdateEx(pUdateIn, lcid, dwFlags, pDateOut);
+}
+
+/***********************************************************************
  *              VarUdateFromDate [OLEAUT32.331]
  *
  * Convert a variant VT_DATE into an unpacked format date and time.
@@ -1473,6 +1515,8 @@
 #define B_EXPONENT_START      0x4
 #define B_INEXACT_ZEROS       0x8
 #define B_LEADING_ZERO        0x10
+#define B_PROCESSING_HEX      0x20
+#define B_PROCESSING_OCT      0x40
 
 /**********************************************************************
  *              VarParseNumFromStr [OLEAUT32.46]
@@ -1590,6 +1634,23 @@
     chars.cCurrencyDigitSeperator = chars.cDigitSeperator;
   }
 
+  if ((*lpszStr == '&' && (*(lpszStr+1) == 'H' || *(lpszStr+1) == 'h')) &&
+    pNumprs->dwInFlags & NUMPRS_HEX_OCT)
+  {
+      dwState |= B_PROCESSING_HEX;
+      pNumprs->dwOutFlags |= NUMPRS_HEX_OCT;
+      cchUsed=cchUsed+2;
+      lpszStr=lpszStr+2;
+  }
+  else if ((*lpszStr == '&' && (*(lpszStr+1) == 'O' || *(lpszStr+1) == 'o')) &&
+    pNumprs->dwInFlags & NUMPRS_HEX_OCT)
+  {
+      dwState |= B_PROCESSING_OCT;
+      pNumprs->dwOutFlags |= NUMPRS_HEX_OCT;
+      cchUsed=cchUsed+2;
+      lpszStr=lpszStr+2;
+  }
+
   /* Strip Leading zeros */
   while (*lpszStr == '0')
   {
@@ -1607,14 +1668,14 @@
         int exponentSize = 0;
         if (dwState & B_EXPONENT_START)
         {
+          if (!isdigitW(*lpszStr))
+            break; /* No exponent digits - invalid */
           while (*lpszStr == '0')
           {
             /* Skip leading zero's in the exponent */
             cchUsed++;
             lpszStr++;
           }
-          if (!isdigitW(*lpszStr))
-            break; /* No exponent digits - invalid */
         }
 
         while (isdigitW(*lpszStr))
@@ -1633,7 +1694,8 @@
       }
       else
       {
-        if (pNumprs->cDig >= iMaxDigits)
+        if ((pNumprs->cDig >= iMaxDigits) && !(dwState & B_PROCESSING_HEX)
+          && !(dwState & B_PROCESSING_OCT))
         {
           pNumprs->dwOutFlags |= NUMPRS_INEXACT;
 
@@ -1648,8 +1710,13 @@
         }
         else
         {
+          if ((dwState & B_PROCESSING_OCT) && ((*lpszStr == '8') || (*lpszStr == '9'))) {
+            return DISP_E_TYPEMISMATCH;
+          }
+
           if (pNumprs->dwOutFlags & NUMPRS_DECIMAL)
             pNumprs->nPwr10--; /* Count decimal points in nPwr10 */
+
           rgbTmp[pNumprs->cDig] = *lpszStr - '0';
         }
         pNumprs->cDig++;
@@ -1668,13 +1735,6 @@
       pNumprs->dwOutFlags |= NUMPRS_DECIMAL;
       cchUsed++;
 
-      /* Remove trailing zeros from the whole number part */
-      while (pNumprs->cDig > 1 && !rgbTmp[pNumprs->cDig - 1])
-      {
-        pNumprs->nPwr10++;
-        pNumprs->cDig--;
-      }
-
       /* If we have no digits so far, skip leading zeros */
       if (!pNumprs->cDig)
       {
@@ -1683,6 +1743,7 @@
           dwState |= B_LEADING_ZERO;
           cchUsed++;
           lpszStr++;
+          pNumprs->nPwr10--;
         }
       }
     }
@@ -1703,6 +1764,24 @@
       dwState |= B_NEGATIVE_EXPONENT;
       cchUsed++;
     }
+    else if (((*lpszStr >= 'a' && *lpszStr <= 'f') ||
+             (*lpszStr >= 'A' && *lpszStr <= 'F')) &&
+             dwState & B_PROCESSING_HEX)
+    {
+      if (pNumprs->cDig >= iMaxDigits)
+      {
+        return DISP_E_OVERFLOW;
+      }
+      else
+      {
+        if (*lpszStr >= 'a')
+          rgbTmp[pNumprs->cDig] = *lpszStr - 'a' + 10;
+        else
+          rgbTmp[pNumprs->cDig] = *lpszStr - 'A' + 10;
+      }
+      pNumprs->cDig++;
+      cchUsed++;
+    }
     else
       break; /* Stop at an unrecognised character */
 
@@ -1733,25 +1812,29 @@
     /* cDig of X and writes X+Y where Y>=0 number of digits to rgbDig */
     memcpy(rgbDig, rgbTmp, pNumprs->cDig * sizeof(BYTE));
 
-    while (pNumprs->cDig > 1 && !rgbTmp[pNumprs->cDig - 1])
-    {
-      if (pNumprs->dwOutFlags & NUMPRS_DECIMAL)
-        pNumprs->nPwr10--;
-      else
-        pNumprs->nPwr10++;
-
-      pNumprs->cDig--;
+    if (dwState & B_PROCESSING_HEX) {
+      /* hex numbers have always the same format */
+      pNumprs->nPwr10=0;
+      pNumprs->nBaseShift=4;
+    } else {
+      if (dwState & B_PROCESSING_OCT) {
+        /* oct numbers have always the same format */
+        pNumprs->nPwr10=0;
+        pNumprs->nBaseShift=3;
+      } else {
+        while (pNumprs->cDig > 1 && !rgbTmp[pNumprs->cDig - 1])
+        {
+          pNumprs->nPwr10++;
+          pNumprs->cDig--;
+        }
+      }
     }
   } else
   {
     /* Remove trailing zeros from the last (whole number or decimal) part */
     while (pNumprs->cDig > 1 && !rgbTmp[pNumprs->cDig - 1])
     {
-      if (pNumprs->dwOutFlags & NUMPRS_DECIMAL)
-        pNumprs->nPwr10--;
-      else
-        pNumprs->nPwr10++;
-
+      pNumprs->nPwr10++;
       pNumprs->cDig--;
     }
   }
@@ -1875,7 +1958,110 @@
   if (pNumprs->nBaseShift)
   {
     /* nBaseShift indicates a hex or octal number */
-    FIXME("nBaseShift=%d not yet implemented, returning overflow\n", pNumprs->nBaseShift);
+    ULONG64 ul64 = 0;
+    LONG64 l64;
+    int i;
+
+    /* Convert the hex or octal number string into a UI64 */
+    for (i = 0; i < pNumprs->cDig; i++)
+    {
+      if (ul64 > ((UI8_MAX>>pNumprs->nBaseShift) - rgbDig[i]))
+      {
+        TRACE("Overflow multiplying digits\n");
+        return DISP_E_OVERFLOW;
+      }
+      ul64 = (ul64<<pNumprs->nBaseShift) + rgbDig[i];
+    }
+
+    /* also make a negative representation */
+    l64=-ul64;
+
+    /* Try signed and unsigned types in size order */
+    if (dwVtBits & VTBIT_I1 && ((ul64 <= I1_MAX)||(l64 >= I1_MIN)))
+    {
+      V_VT(pVarDst) = VT_I1;
+      if (ul64 <= I1_MAX)
+          V_I1(pVarDst) = ul64;
+      else
+          V_I1(pVarDst) = l64;
+      return S_OK;
+    }
+    else if (dwVtBits & VTBIT_UI1 && ul64 <= UI1_MAX)
+    {
+      V_VT(pVarDst) = VT_UI1;
+      V_UI1(pVarDst) = ul64;
+      return S_OK;
+    }
+    else if (dwVtBits & VTBIT_I2 && ((ul64 <= I2_MAX)||(l64 >= I2_MIN)))
+    {
+      V_VT(pVarDst) = VT_I2;
+      if (ul64 <= I2_MAX)
+          V_I2(pVarDst) = ul64;
+      else
+          V_I2(pVarDst) = l64;
+      return S_OK;
+    }
+    else if (dwVtBits & VTBIT_UI2 && ul64 <= UI2_MAX)
+    {
+      V_VT(pVarDst) = VT_UI2;
+      V_UI2(pVarDst) = ul64;
+      return S_OK;
+    }
+    else if (dwVtBits & VTBIT_I4 && ((ul64 <= I4_MAX)||(l64 >= I4_MIN)))
+    {
+      V_VT(pVarDst) = VT_I4;
+      if (ul64 <= I4_MAX)
+          V_I4(pVarDst) = ul64;
+      else
+          V_I4(pVarDst) = l64;
+      return S_OK;
+    }
+    else if (dwVtBits & VTBIT_UI4 && ul64 <= UI4_MAX)
+    {
+      V_VT(pVarDst) = VT_UI4;
+      V_UI4(pVarDst) = ul64;
+      return S_OK;
+    }
+    else if (dwVtBits & VTBIT_I8 && ((ul64 <= I4_MAX)||(l64>=I4_MIN)))
+    {
+      V_VT(pVarDst) = VT_I8;
+      V_I8(pVarDst) = ul64;
+      return S_OK;
+    }
+    else if (dwVtBits & VTBIT_UI8)
+    {
+      V_VT(pVarDst) = VT_UI8;
+      V_UI8(pVarDst) = ul64;
+      return S_OK;
+    }
+    else if ((dwVtBits & REAL_VTBITS) == VTBIT_DECIMAL)
+    {
+      V_VT(pVarDst) = VT_DECIMAL;
+      DEC_SIGNSCALE(&V_DECIMAL(pVarDst)) = SIGNSCALE(DECIMAL_POS,0);
+      DEC_HI32(&V_DECIMAL(pVarDst)) = 0;
+      DEC_LO64(&V_DECIMAL(pVarDst)) = ul64;
+      return S_OK;
+    }
+    else if (dwVtBits & VTBIT_R4 && ((ul64 <= I4_MAX)||(l64 >= I4_MIN)))
+    {
+      V_VT(pVarDst) = VT_R4;
+      if (ul64 <= I4_MAX)
+          V_R4(pVarDst) = ul64;
+      else
+          V_R4(pVarDst) = l64;
+      return S_OK;
+    }
+    else if (dwVtBits & VTBIT_R8 && ((ul64 <= I4_MAX)||(l64 >= I4_MIN)))
+    {
+      V_VT(pVarDst) = VT_R8;
+      if (ul64 <= I4_MAX)
+          V_R8(pVarDst) = ul64;
+      else
+          V_R8(pVarDst) = l64;
+      return S_OK;
+    }
+
+    TRACE("Overflow: possible return types: 0x%lx, value: %s\n", dwVtBits, wine_dbgstr_longlong(ul64));
     return DISP_E_OVERFLOW;
   }
 
@@ -2146,7 +2332,7 @@
 
     while (divisor10 > 10)
     {
-      if (whole < dblMinimums[10])
+      if (whole < dblMinimums[10] && whole != 0)
       {
         dwVtBits &= ~(VTBIT_R4|VTBIT_R8|VTBIT_CY); /* Underflow */
         bOverflow = TRUE;
@@ -2157,7 +2343,7 @@
     }
     if (divisor10)
     {
-      if (whole < dblMinimums[divisor10])
+      if (whole < dblMinimums[divisor10] && whole != 0)
       {
         dwVtBits &= ~(VTBIT_R4|VTBIT_R8|VTBIT_CY); /* Underflow */
         bOverflow = TRUE;
@@ -2899,84 +3085,260 @@
 /**********************************************************************
  *              VarOr [OLEAUT32.157]
  *
+ * Perform a logical or (OR) operation on two variants.
+ *
+ * PARAMS
+ *  pVarLeft  [I] First variant
+ *  pVarRight [I] Variant to OR with pVarLeft
+ *  pVarOut   [O] Destination for OR result
+ *
+ * RETURNS
+ *  Success: S_OK. pVarOut contains the result of the operation with its type
+ *           taken from the table listed under VarXor().
+ *  Failure: An HRESULT error code indicating the error.
+ *
+ * NOTES
+ *  See the Notes section of VarXor() for further information.
  */
-HRESULT WINAPI VarOr(LPVARIANT left, LPVARIANT right, LPVARIANT result)
+HRESULT WINAPI VarOr(LPVARIANT pVarLeft, LPVARIANT pVarRight, LPVARIANT pVarOut)
 {
-    HRESULT rc = E_FAIL;
+    VARTYPE vt = VT_I4;
+    VARIANT varLeft, varRight, varStr;
+    HRESULT hRet;
+
+    TRACE("(%p->(%s%s),%p->(%s%s),%p)\n", pVarLeft, debugstr_VT(pVarLeft),
+          debugstr_VF(pVarLeft), pVarRight, debugstr_VT(pVarRight),
+          debugstr_VF(pVarRight), pVarOut);
+
+    if (V_EXTRA_TYPE(pVarLeft) || V_EXTRA_TYPE(pVarRight) ||
+        V_VT(pVarLeft) == VT_UNKNOWN || V_VT(pVarRight) == VT_UNKNOWN ||
+        V_VT(pVarLeft) == VT_DISPATCH || V_VT(pVarRight) == VT_DISPATCH ||
+        V_VT(pVarLeft) == VT_RECORD || V_VT(pVarRight) == VT_RECORD)
+        return DISP_E_BADVARTYPE;
 
-    TRACE("(%p->(%s%s),%p->(%s%s),%p)\n", left, debugstr_VT(left),
-          debugstr_VF(left), right, debugstr_VT(right), debugstr_VF(right), result);
+    V_VT(&varLeft) = V_VT(&varRight) = V_VT(&varStr) = VT_EMPTY;
 
-    if ((V_VT(left)&VT_TYPEMASK) == VT_BOOL &&
-        (V_VT(right)&VT_TYPEMASK) == VT_BOOL) {
+    if (V_VT(pVarLeft) == VT_NULL || V_VT(pVarRight) == VT_NULL)
+    {
+        /* NULL OR Zero is NULL, NULL OR value is value */
+        if (V_VT(pVarLeft) == VT_NULL)
+            pVarLeft = pVarRight; /* point to the non-NULL var */
 
-        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;
+        V_VT(pVarOut) = VT_NULL;
+        V_I4(pVarOut) = 0;
 
-    } else {
-        /* Integers */
-        BOOL         lOk        = TRUE;
-        BOOL         rOk        = TRUE;
-        LONGLONG     lVal = -1;
-        LONGLONG     rVal = -1;
-        LONGLONG     res  = -1;
-        int          resT = 0; /* Testing has shown I2 & I2 == I2, all else
-                                  becomes I4, even unsigned ints (incl. UI2) */
+        switch (V_VT(pVarLeft))
+        {
+        case VT_DATE: case VT_R8:
+            if (V_R8(pVarLeft))
+                goto VarOr_AsEmpty;
+            return S_OK;
+        case VT_BOOL:
+            if (V_BOOL(pVarLeft))
+                *pVarOut = *pVarLeft;
+            return S_OK;
+         case VT_I2: case VT_UI2:
+            if (V_I2(pVarLeft))
+                goto VarOr_AsEmpty;
+            return S_OK;
+        case VT_I1:
+            if (V_I1(pVarLeft))
+                goto VarOr_AsEmpty;
+            return S_OK;
+        case VT_UI1:
+            if (V_UI1(pVarLeft))
+                *pVarOut = *pVarLeft;
+            return S_OK;
+        case VT_R4:
+            if (V_R4(pVarLeft))
+                goto VarOr_AsEmpty;
+            return S_OK;
+        case VT_I4: case VT_UI4: case VT_INT: case VT_UINT:
+            if (V_I4(pVarLeft))
+                goto VarOr_AsEmpty;
+            return S_OK;
+        case VT_CY:
+            if (V_CY(pVarLeft).int64)
+                goto VarOr_AsEmpty;
+            return S_OK;
+        case VT_I8: case VT_UI8:
+            if (V_I8(pVarLeft))
+                goto VarOr_AsEmpty;
+            return S_OK;
+        case VT_DECIMAL:
+            if (DEC_HI32(&V_DECIMAL(pVarLeft)) || DEC_LO64(&V_DECIMAL(pVarLeft)))
+                goto VarOr_AsEmpty;
+            return S_OK;
+        case VT_BSTR:
+        {
+            VARIANT_BOOL b;
 
-        lOk = TRUE;
-        switch (V_VT(left)&VT_TYPEMASK) {
-        case VT_I1   : lVal = V_UNION(left,cVal);  resT=VT_I4; break;
-        case VT_I2   : lVal = V_UNION(left,iVal);  resT=VT_I2; break;
-        case VT_I4   : lVal = V_UNION(left,lVal);  resT=VT_I4; break;
-        case VT_INT  : lVal = V_UNION(left,lVal);  resT=VT_I4; break;
-        case VT_UI1  : lVal = V_UNION(left,bVal);  resT=VT_I4; break;
-        case VT_UI2  : lVal = V_UNION(left,uiVal); resT=VT_I4; break;
-        case VT_UI4  : lVal = V_UNION(left,ulVal); resT=VT_I4; break;
-        case VT_UINT : lVal = V_UNION(left,ulVal); resT=VT_I4; break;
-        case VT_BOOL : lVal = V_UNION(left,boolVal); resT=VT_I4; break;
-        default: lOk = FALSE;
-        }
+            if (!V_BSTR(pVarLeft))
+                return DISP_E_BADVARTYPE;
 
-        rOk = TRUE;
-        switch (V_VT(right)&VT_TYPEMASK) {
-        case VT_I1   : rVal = V_UNION(right,cVal);  resT=VT_I4; break;
-        case VT_I2   : rVal = V_UNION(right,iVal);  resT=max(VT_I2, resT); break;
-        case VT_I4   : rVal = V_UNION(right,lVal);  resT=VT_I4; break;
-        case VT_INT  : rVal = V_UNION(right,lVal);  resT=VT_I4; break;
-        case VT_UI1  : rVal = V_UNION(right,bVal);  resT=VT_I4; break;
-        case VT_UI2  : rVal = V_UNION(right,uiVal); resT=VT_I4; break;
-        case VT_UI4  : rVal = V_UNION(right,ulVal); resT=VT_I4; break;
-        case VT_UINT : rVal = V_UNION(right,ulVal); resT=VT_I4; break;
-        case VT_BOOL : rVal = V_UNION(right,boolVal); resT=VT_I4; break;
-        default: rOk = FALSE;
+            hRet = VarBoolFromStr(V_BSTR(pVarLeft), LOCALE_USER_DEFAULT, VAR_LOCALBOOL, &b);
+            if (SUCCEEDED(hRet) && b)
+            {
+                V_VT(pVarOut) = VT_BOOL;
+                V_BOOL(pVarOut) = b;
+            }
+            return hRet;
+        }
+        case VT_NULL: case VT_EMPTY:
+            V_VT(pVarOut) = VT_NULL;
+            return S_OK;
+        default:
+            return DISP_E_BADVARTYPE;
         }
+    }
 
-        if (lOk && rOk) {
-            res = (lVal | rVal);
-            V_VT(result) = resT;
-            switch (resT) {
-            case VT_I2   : V_UNION(result,iVal)  = res; break;
-            case VT_I4   : V_UNION(result,lVal)  = res; break;
-            default:
-                FIXME("Unexpected result variant type %x\n", resT);
-                V_UNION(result,lVal)  = res;
-            }
-            rc = S_OK;
+    if (V_VT(pVarLeft) == VT_EMPTY || V_VT(pVarRight) == VT_EMPTY)
+    {
+        if (V_VT(pVarLeft) == VT_EMPTY)
+            pVarLeft = pVarRight; /* point to the non-EMPTY var */
 
-        } else {
-            FIXME("unimplemented part, V_VT(left) == 0x%X, V_VT(right) == 0x%X\n", 
-		V_VT(left) & VT_TYPEMASK, V_VT(right) & VT_TYPEMASK);
+VarOr_AsEmpty:
+        /* Since one argument is empty (0), OR'ing it with the other simply
+         * gives the others value (as 0|x => x). So just convert the other
+         * argument to the required result type.
+         */
+        switch (V_VT(pVarLeft))
+        {
+        case VT_BSTR:
+            if (!V_BSTR(pVarLeft))
+                return DISP_E_BADVARTYPE;
+
+            hRet = VariantCopy(&varStr, pVarLeft);
+            if (FAILED(hRet))
+                goto VarOr_Exit;
+            pVarLeft = &varStr;
+            hRet = VariantChangeType(pVarLeft, pVarLeft, 0, VT_BOOL);
+            if (FAILED(hRet))
+                goto VarOr_Exit;
+            /* Fall Through ... */
+        case VT_EMPTY: case VT_UI1: case VT_BOOL: case VT_I2:
+            V_VT(pVarOut) = VT_I2;
+            break;
+        case VT_DATE: case VT_CY: case VT_DECIMAL: case VT_R4: case VT_R8:
+        case VT_I1: case VT_UI2: case VT_I4: case VT_UI4:
+        case VT_INT: case VT_UINT: case VT_UI8:
+            V_VT(pVarOut) = VT_I4;
+            break;
+        case VT_I8:
+            V_VT(pVarOut) = VT_I8;
+            break;
+        default:
+            return DISP_E_BADVARTYPE;
         }
+        hRet = VariantCopy(&varLeft, pVarLeft);
+        if (FAILED(hRet))
+            goto VarOr_Exit;
+        pVarLeft = &varLeft;
+        hRet = VariantChangeType(pVarOut, pVarLeft, 0, V_VT(pVarOut));
+        goto VarOr_Exit;
     }
 
-    TRACE("returning 0x%8lx (%s%s),%ld\n", rc, debugstr_VT(result),
-          debugstr_VF(result), V_VT(result) == VT_I4 ? V_I4(result) : V_I2(result));
-    return rc;
+    if (V_VT(pVarLeft) == VT_BOOL && V_VT(pVarRight) == VT_BOOL)
+    {
+        V_VT(pVarOut) = VT_BOOL;
+        V_BOOL(pVarOut) = V_BOOL(pVarLeft) | V_BOOL(pVarRight);
+        return S_OK;
+    }
+
+    if (V_VT(pVarLeft) == VT_UI1 && V_VT(pVarRight) == VT_UI1)
+    {
+        V_VT(pVarOut) = VT_UI1;
+        V_UI1(pVarOut) = V_UI1(pVarLeft) | V_UI1(pVarRight);
+        return S_OK;
+    }
+
+    if (V_VT(pVarLeft) == VT_BSTR)
+    {
+        hRet = VariantCopy(&varStr, pVarLeft);
+        if (FAILED(hRet))
+            goto VarOr_Exit;
+        pVarLeft = &varStr;
+        hRet = VariantChangeType(pVarLeft, pVarLeft, 0, VT_BOOL);
+        if (FAILED(hRet))
+            goto VarOr_Exit;
+    }
+
+    if (V_VT(pVarLeft) == VT_BOOL &&
+        (V_VT(pVarRight) == VT_BOOL || V_VT(pVarRight) == VT_BSTR))
+    {
+        vt = VT_BOOL;
+    }
+    else if ((V_VT(pVarLeft) == VT_BOOL || V_VT(pVarLeft) == VT_UI1 ||
+        V_VT(pVarLeft) == VT_I2 || V_VT(pVarLeft) == VT_BSTR) &&
+        (V_VT(pVarRight) == VT_BOOL || V_VT(pVarRight) == VT_UI1 ||
+        V_VT(pVarRight) == VT_I2 || V_VT(pVarRight) == VT_BSTR))
+    {
+        vt = VT_I2;
+    }
+    else if (V_VT(pVarLeft) == VT_I8 || V_VT(pVarRight) == VT_I8)
+    {
+        if (V_VT(pVarLeft) == VT_INT || V_VT(pVarRight) == VT_INT)
+            return DISP_E_TYPEMISMATCH;
+        vt = VT_I8;
+    }
+
+    hRet = VariantCopy(&varLeft, pVarLeft);
+    if (FAILED(hRet))
+        goto VarOr_Exit;
+
+    hRet = VariantCopy(&varRight, pVarRight);
+    if (FAILED(hRet))
+        goto VarOr_Exit;
+
+    if (vt == VT_I4 && V_VT(&varLeft) == VT_UI4)
+        V_VT(&varLeft) = VT_I4; /* Don't overflow */
+    else
+    {
+        double d;
+
+        if (V_VT(&varLeft) == VT_BSTR &&
+            FAILED(VarR8FromStr(V_BSTR(&varLeft), LOCALE_USER_DEFAULT, 0, &d)))
+            hRet = VariantChangeType(&varLeft, &varLeft, VARIANT_LOCALBOOL, VT_BOOL);
+        if (SUCCEEDED(hRet) && V_VT(&varLeft) != vt)
+            hRet = VariantChangeType(&varLeft, &varLeft, 0, vt);
+        if (FAILED(hRet))
+            goto VarOr_Exit;
+    }
+
+    if (vt == VT_I4 && V_VT(&varRight) == VT_UI4)
+        V_VT(&varRight) = VT_I4; /* Don't overflow */
+    else
+    {
+        double d;
+
+        if (V_VT(&varRight) == VT_BSTR &&
+            FAILED(VarR8FromStr(V_BSTR(&varRight), LOCALE_USER_DEFAULT, 0, &d)))
+            hRet = VariantChangeType(&varRight, &varRight, VARIANT_LOCALBOOL, VT_BOOL);
+        if (SUCCEEDED(hRet) && V_VT(&varRight) != vt)
+            hRet = VariantChangeType(&varRight, &varRight, 0, vt);
+        if (FAILED(hRet))
+            goto VarOr_Exit;
+    }
+
+    V_VT(pVarOut) = vt;
+    if (vt == VT_I8)
+    {
+        V_I8(pVarOut) = V_I8(&varLeft) | V_I8(&varRight);
+    }
+    else if (vt == VT_I4)
+    {
+        V_I4(pVarOut) = V_I4(&varLeft) | V_I4(&varRight);
+    }
+    else
+    {
+        V_I2(pVarOut) = V_I2(&varLeft) | V_I2(&varRight);
+    }
+
+VarOr_Exit:
+    VariantClear(&varStr);
+    VariantClear(&varLeft);
+    VariantClear(&varRight);
+    return hRet;
 }
 
 /**********************************************************************
@@ -3053,9 +3415,12 @@
     case VT_UINT:
     case VT_UI4:
     case VT_UI8:
+        /* No-Op */
+        break;
     case VT_EMPTY:
+        V_VT(pVarOut) = VT_I2;
     case VT_NULL:
-        /* No-Op */
+        V_I2(pVarOut) = 0;
         break;
     default:
         hRet = DISP_E_BADVARTYPE;
@@ -3221,6 +3586,211 @@
 }
 
 /**********************************************************************
+ *              VarXor [OLEAUT32.167]
+ *
+ * Perform a logical exclusive-or (XOR) operation on two variants.
+ *
+ * PARAMS
+ *  pVarLeft  [I] First variant
+ *  pVarRight [I] Variant to XOR with pVarLeft
+ *  pVarOut   [O] Destination for XOR result
+ *
+ * RETURNS
+ *  Success: S_OK. pVarOut contains the result of the operation with its type
+ *           taken from the table below).
+ *  Failure: An HRESULT error code indicating the error.
+ *
+ * NOTES
+ *  - Neither pVarLeft or pVarRight are modified by this function.
+ *  - This function does not process by-reference variants.
+ *  - Input types of VT_BSTR may be numeric strings or boolean text.
+ *  - The type of result stored in pVarOut depends on the types of pVarLeft
+ *    and pVarRight, and will be one of VT_UI1, VT_I2, VT_I4, VT_I8, VT_BOOL,
+ *    or VT_NULL if the function succeeds.
+ *  - Type promotion is inconsistent and as a result certain combinations of
+ *    values will return DISP_E_OVERFLOW even when they could be represented.
+ *    This matches the behaviour of native oleaut32.
+ */
+HRESULT WINAPI VarXor(LPVARIANT pVarLeft, LPVARIANT pVarRight, LPVARIANT pVarOut)
+{
+    VARTYPE vt;
+    VARIANT varLeft, varRight;
+    double d;
+    HRESULT hRet;
+
+    TRACE("(%p->(%s%s),%p->(%s%s),%p)\n", pVarLeft, debugstr_VT(pVarLeft),
+          debugstr_VF(pVarLeft), pVarRight, debugstr_VT(pVarRight),
+          debugstr_VF(pVarRight), pVarOut);
+
+    if (V_EXTRA_TYPE(pVarLeft) || V_EXTRA_TYPE(pVarRight) ||
+        V_VT(pVarLeft) > VT_UINT || V_VT(pVarRight) > VT_UINT ||
+        V_VT(pVarLeft) == VT_VARIANT || V_VT(pVarRight) == VT_VARIANT ||
+        V_VT(pVarLeft) == VT_UNKNOWN || V_VT(pVarRight) == VT_UNKNOWN ||
+        V_VT(pVarLeft) == (VARTYPE)15 || V_VT(pVarRight) == (VARTYPE)15 ||
+        V_VT(pVarLeft) == VT_ERROR || V_VT(pVarRight) == VT_ERROR)
+        return DISP_E_BADVARTYPE;
+
+    if (V_VT(pVarLeft) == VT_NULL || V_VT(pVarRight) == VT_NULL)
+    {
+        /* NULL XOR anything valid is NULL */
+        V_VT(pVarOut) = VT_NULL;
+        return S_OK;
+    }
+
+    /* Copy our inputs so we don't disturb anything */
+    V_VT(&varLeft) = V_VT(&varRight) = VT_EMPTY;
+
+    hRet = VariantCopy(&varLeft, pVarLeft);
+    if (FAILED(hRet))
+        goto VarXor_Exit;
+
+    hRet = VariantCopy(&varRight, pVarRight);
+    if (FAILED(hRet))
+        goto VarXor_Exit;
+
+    /* Try any strings first as numbers, then as VT_BOOL */
+    if (V_VT(&varLeft) == VT_BSTR)
+    {
+        hRet = VarR8FromStr(V_BSTR(&varLeft), LOCALE_USER_DEFAULT, 0, &d);
+        hRet = VariantChangeType(&varLeft, &varLeft, VARIANT_LOCALBOOL,
+                                 FAILED(hRet) ? VT_BOOL : VT_I4);
+        if (FAILED(hRet))
+            goto VarXor_Exit;
+    }
+
+    if (V_VT(&varRight) == VT_BSTR)
+    {
+        hRet = VarR8FromStr(V_BSTR(&varRight), LOCALE_USER_DEFAULT, 0, &d);
+        hRet = VariantChangeType(&varRight, &varRight, VARIANT_LOCALBOOL,
+                                 FAILED(hRet) ? VT_BOOL : VT_I4);
+        if (FAILED(hRet))
+            goto VarXor_Exit;
+    }
+
+    /* Determine the result type */
+    if (V_VT(&varLeft) == VT_I8 || V_VT(&varRight) == VT_I8)
+    {
+        if (V_VT(pVarLeft) == VT_INT || V_VT(pVarRight) == VT_INT)
+            return DISP_E_TYPEMISMATCH;
+        vt = VT_I8;
+    }
+    else
+    {
+        switch ((V_VT(&varLeft) << 16) | V_VT(&varRight))
+        {
+        case (VT_BOOL  << 16) | VT_BOOL:
+            vt = VT_BOOL;
+            break;
+        case (VT_UI1   << 16) | VT_UI1:
+            vt = VT_UI1;
+            break;
+        case (VT_EMPTY << 16) | VT_EMPTY:
+        case (VT_EMPTY << 16) | VT_UI1:
+        case (VT_EMPTY << 16) | VT_I2:
+        case (VT_EMPTY << 16) | VT_BOOL:
+        case (VT_UI1   << 16) | VT_EMPTY:
+        case (VT_UI1   << 16) | VT_I2:
+        case (VT_UI1   << 16) | VT_BOOL:
+        case (VT_I2    << 16) | VT_EMPTY:
+        case (VT_I2    << 16) | VT_UI1:
+        case (VT_I2    << 16) | VT_I2:
+        case (VT_I2    << 16) | VT_BOOL:
+        case (VT_BOOL  << 16) | VT_EMPTY:
+        case (VT_BOOL  << 16) | VT_UI1:
+        case (VT_BOOL  << 16) | VT_I2:
+            vt = VT_I2;
+            break;
+        default:
+            vt = VT_I4;
[truncated at 1000 lines; 153 more skipped]

reactos/lib/oleaut32
variant.h 1.3 -> 1.4
diff -u -r1.3 -r1.4
--- variant.h	29 Feb 2004 16:24:54 -0000	1.3
+++ variant.h	2 Dec 2004 19:38:49 -0000	1.4
@@ -21,10 +21,10 @@
 #define NONAMELESSSTRUCT
 #include "windef.h"
 #include "winerror.h"
+#include "objbase.h"
 #include "oleauto.h"
 #include <math.h>
 
-
 /* Get just the type from a variant pointer */
 #define V_TYPE(v)  (V_VT((v)) & VT_TYPEMASK)
 
@@ -82,15 +82,13 @@
 #endif
 
 /* Macros for getting at a DECIMAL's parts */
-#ifndef DEC_LO64
-#define DEC_SIGN(d)      ((d)->u.s.sign)
-#define DEC_SCALE(d)     ((d)->u.s.scale)
-#define DEC_SIGNSCALE(d) ((d)->u.signscale)
+#define DEC_SIGN(d)      ((d)->sign)
+#define DEC_SCALE(d)     ((d)->scale)
+#define DEC_SIGNSCALE(d) ((d)->signscale)
 #define DEC_HI32(d)      ((d)->Hi32)
-#define DEC_MID32(d)     ((d)->DUMMYUNIONNAME2.DUMMYSTRUCTNAME2.Mid32)
-#define DEC_LO32(d)      ((d)->DUMMYUNIONNAME2.DUMMYSTRUCTNAME2.Lo32)
-#define DEC_LO64(d)      ((d)->DUMMYUNIONNAME2.Lo64)
-#endif
+#define DEC_MID32(d)     ((d)->Mid32)
+#define DEC_LO32(d)      ((d)->Lo32)
+#define DEC_LO64(d)      ((d)->Lo64)
 
 #define DEC_MAX_SCALE    28 /* Maximum scale for a decimal */
 

reactos/lib/oleaut32
vartype.c 1.9 -> 1.10
diff -u -r1.9 -r1.10
--- vartype.c	29 Feb 2004 16:37:23 -0000	1.9
+++ vartype.c	2 Dec 2004 19:38:49 -0000	1.10
@@ -17,8 +17,11 @@
  * License along with this library; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
+
+#define COBJMACROS
 #define NONAMELESSUNION
 #define NONAMELESSSTRUCT
+
 #include "wine/debug.h"
 #include "wine/unicode.h"
 #include "winbase.h"
@@ -27,7 +30,7 @@
 #include "variant.h"
 #include "resource.h"
 
-WINE_DEFAULT_DEBUG_CHANNEL(ole);
+WINE_DEFAULT_DEBUG_CHANNEL(variant);
 
 extern HMODULE OLEAUT32_hModule;
 
@@ -1356,7 +1359,7 @@
  * Convert a VT_I2 to a VT_I4.
  *
  * PARAMS
- *  iIn     [I] Source
+ *  sIn     [I] Source
  *  piOut   [O] Destination
  *
  * RETURNS
@@ -3848,7 +3851,7 @@
  * RETURNS
  *  Success: VARCMP_LT, VARCMP_EQ or VARCMP_GT indicating that the value to
  *           compare is less, equal or greater than source respectively.
- *  Failure: DISP_E_OVERFLOW, if overflow occurs during the comparason
+ *  Failure: DISP_E_OVERFLOW, if overflow occurs during the comparison
  */
 HRESULT WINAPI VarCyCmp(const CY cyLeft, const CY cyRight)
 {
@@ -3882,7 +3885,7 @@
  * RETURNS
  *  Success: VARCMP_LT, VARCMP_EQ or VARCMP_GT indicating that dblRight is
  *           less than, equal to or greater than cyLeft respectively.
- *  Failure: DISP_E_OVERFLOW, if overflow occurs during the comparason
+ *  Failure: DISP_E_OVERFLOW, if overflow occurs during the comparison
  */
 HRESULT WINAPI VarCyCmpR8(const CY cyLeft, double dblRight)
 {
@@ -4574,7 +4577,7 @@
  */
 HRESULT WINAPI VarDecFix(const DECIMAL* pDecIn, DECIMAL* pDecOut)
 {
-  if (DEC_SIGN(pDecOut) & ~DECIMAL_NEG)
+  if (DEC_SIGN(pDecIn) & ~DECIMAL_NEG)
     return E_INVALIDARG;
 
   if (!DEC_SCALE(pDecIn))
@@ -4606,10 +4609,10 @@
  */
 HRESULT WINAPI VarDecInt(const DECIMAL* pDecIn, DECIMAL* pDecOut)
 {
-  if (DEC_SIGN(pDecOut) & ~DECIMAL_NEG)
+  if (DEC_SIGN(pDecIn) & ~DECIMAL_NEG)
     return E_INVALIDARG;
 
-  if (!(DEC_SIGN(pDecOut) & DECIMAL_NEG) || !DEC_SCALE(pDecIn))
+  if (!(DEC_SIGN(pDecIn) & DECIMAL_NEG) || !DEC_SCALE(pDecIn))
     return VarDecFix(pDecIn, pDecOut); /* The same, if +ve or no fractionals */
 
   FIXME("semi-stub!\n");
@@ -4677,7 +4680,7 @@
  * RETURNS
  *  Success: VARCMP_LT, VARCMP_EQ or VARCMP_GT indicating that pDecLeft
  *           is less than, equal to or greater than pDecRight respectively.
- *  Failure: DISP_E_OVERFLOW, if overflow occurs during the comparason
+ *  Failure: DISP_E_OVERFLOW, if overflow occurs during the comparison
  */
 HRESULT WINAPI VarDecCmp(const DECIMAL* pDecLeft, const DECIMAL* pDecRight)
 {
@@ -4713,7 +4716,7 @@
  * RETURNS
  *  Success: VARCMP_LT, VARCMP_EQ or VARCMP_GT indicating that dblRight
  *           is less than, equal to or greater than pDecLeft respectively.
- *  Failure: DISP_E_OVERFLOW, if overflow occurs during the comparason
+ *  Failure: DISP_E_OVERFLOW, if overflow occurs during the comparison
  */
 HRESULT WINAPI VarDecCmpR8(const DECIMAL* pDecLeft, double dblRight)
 {
@@ -5706,7 +5709,7 @@
  * PARAMS
  *  pbstrLeft  [I] Source
  *  pbstrRight [I] Value to compare
- *  lcid       [I] LCID for the comparason
+ *  lcid       [I] LCID for the comparison
  *  dwFlags    [I] Flags to pass directly to CompareStringW().
  *
  * RETURNS

reactos/w32api/include
oaidl.h 1.8 -> 1.9
diff -u -r1.8 -r1.9
--- oaidl.h	1 Dec 2004 20:06:15 -0000	1.8
+++ oaidl.h	2 Dec 2004 19:38:49 -0000	1.9
@@ -11,9 +11,10 @@
 #define __VARIANT_NAME_1 n1
 #define __VARIANT_NAME_2 n2
 #define __VARIANT_NAME_3 n3
-#define __VARIANT_NAME_4 n4
+#define __VARIANT_NAME_4 brecVal
 #else
 #define __tagVARIANT
+#define __tagBRECORD
 #define __VARIANT_NAME_1
 #define __VARIANT_NAME_2
 #define __VARIANT_NAME_3
@@ -238,7 +239,7 @@
 		ULONG  *pulVal;
 		INT  *pintVal;
 		UINT  *puintVal;
-		_ANONYMOUS_STRUCT struct {
+		_ANONYMOUS_STRUCT struct __tagBRECORD {
 			PVOID pvRecord;
 			struct IRecordInfo *pRecInfo;
 		} __VARIANT_NAME_4;

reactos/w32api/include
oleauto.h 1.12 -> 1.13
diff -u -r1.12 -r1.13
--- oleauto.h	1 Dec 2004 20:06:15 -0000	1.12
+++ oleauto.h	2 Dec 2004 19:38:49 -0000	1.13
@@ -37,9 +37,13 @@
 #if __STDC__ || defined(NONAMELESSUNION)
 #define V_UNION(X,Y) ((X)->__VARIANT_NAME_1.__VARIANT_NAME_2.__VARIANT_NAME_3.Y)
 #define V_VT(X) ((X)->__VARIANT_NAME_1.__VARIANT_NAME_2.vt)
+#define V_RECORDINFO(X) ((X)->__VARIANT_NAME_1.__VARIANT_NAME_2.__VARIANT_NAME_3.__VARIANT_NAME_4.pRecInfo)
+#define V_RECORD(X) ((X)->__VARIANT_NAME_1.__VARIANT_NAME_2.__VARIANT_NAME_3.__VARIANT_NAME_4.pvRecord)
 #else
 #define V_UNION(X,Y) ((X)->Y)
 #define V_VT(X) ((X)->vt)
+#define V_RECORDINFO(X) ((X)->pRecInfo)
+#define V_RECORD(X) ((X)->pvRecord)
 #endif
 #define V_BOOL(X) V_UNION(X,boolVal)
 #define V_ISBYREF(X) (V_VT(X)&VT_BYREF)

reactos/w32api/include
winuser.h 1.10 -> 1.11
diff -u -r1.10 -r1.11
--- winuser.h	20 Nov 2004 15:50:46 -0000	1.10
+++ winuser.h	2 Dec 2004 19:38:49 -0000	1.11
@@ -845,6 +845,10 @@
 #define COLOR_HOTLIGHT 26
 #define COLOR_GRADIENTACTIVECAPTION 27
 #define COLOR_GRADIENTINACTIVECAPTION 28
+#if WINVER >= 0x0501
+#define COLOR_MENUHILIGHT 29
+#define COLOR_MENUBAR 30
+#endif
 #define CTLCOLOR_MSGBOX 0
 #define CTLCOLOR_EDIT 1
 #define CTLCOLOR_LISTBOX 2

reactos/w32api/include
wtypes.h 1.5 -> 1.6
diff -u -r1.5 -r1.6
--- wtypes.h	2 Mar 2004 10:25:59 -0000	1.5
+++ wtypes.h	2 Dec 2004 19:38:49 -0000	1.6
@@ -11,23 +11,6 @@
 extern "C" {
 #endif
 
-#ifdef NONAMELESSUNION
-#define DEC_SIGN(d) ((d)->DUMMYUNIONNAME.DUMMYSTRUCTNAME.sign)
-#define DEC_SCALE(d) ((d)->DUMMYUNIONNAME.DUMMYSTRUCTNAME.scale)
-#define DEC_SIGNSCALE(d) ((d)->DUMMYUNIONNAME.signscale)
-#define DEC_MID32(d) ((d)->DUMMYUNIONNAME2.DUMMYSTRUCTNAME2.Mid32)
-#define DEC_LO32(d) ((d)->DUMMYUNIONNAME2.DUMMYSTRUCTNAME2.Lo32)
-#define DEC_LO64(d) ((d)->DUMMYUNIONNAME2.Lo64)
-#else
-#define DEC_SIGN(d) ((d)->sign)
-#define DEC_SCALE(d) ((d)->scale)
-#define DEC_SIGNSCALE(d) ((d)->signscale)
-#define DEC_MID32(d) ((d)->Mid32)
-#define DEC_LO32(d) ((d)->Lo32)
-#define DEC_LO64(d) ((d)->Lo64)
-#endif
-#define DEC_HI32(d) ((d)->Hi32)
-
 #define IID_NULL GUID_NULL
 #define CLSID_NULL GUID_NULL
 #define CBPCLIPDATA(d) ((d).cbSize-sizeof((d).ulClipFmt))
@@ -160,21 +143,21 @@
 typedef double DOUBLE;
 typedef struct tagDEC {
 	USHORT wReserved;
-	_ANONYMOUS_UNION union {
-		_ANONYMOUS_STRUCT struct {
+	union {
+		struct {
 			BYTE scale;
 			BYTE sign;
-		}_STRUCT_NAME(s);
+		};
 		USHORT signscale;
-	} DUMMYUNIONNAME;
+	};
 	ULONG Hi32;
-	_ANONYMOUS_UNION union {
-		_ANONYMOUS_STRUCT struct {
+	union {
+		struct {
 			ULONG Lo32;
 			ULONG Mid32;
-		}_STRUCT_NAME(s2);
+		};
 		ULONGLONG Lo64;
-	} DUMMYUNIONNAME2;
+	};
 } DECIMAL;
 typedef void *HMETAFILEPICT;
 #ifdef __cplusplus
CVSspam 0.2.8