Sync to Wine-20050725:
authorGé van Geldorp <ge@gse.nl>
Fri, 12 Aug 2005 17:30:09 +0000 (17:30 +0000)
committerGé van Geldorp <ge@gse.nl>
Fri, 12 Aug 2005 17:30:09 +0000 (17:30 +0000)
Huw Davies <huw@codeweavers.com> for Mandriva
- Cope with the index in a import table entry being a typeinfo index
  rather than a guid offset.
Robert Shearman <rob@codeweavers.com>
- Document active object and variant functions.
- Rename OLEAUT32_Dll* Functions to Dll*.
- IRpcStubBuffer_Disconnect can be called multiple times.
- Release TypeLib when freeing stub buffer.
- Fix confusion between number of characters and number of bytes in
  unmarshaling BSTRs. Convert it all to characters for consistency with
  the BSTR_User* routines.
- Marshal and unmarshal TKIND_ENUM and TKIND_ALIAS.
- Fix VT_BYREF|VT_UNKNOWN return values by comparing the correct value
  with VT_UNKNOWN and VT_DISPATCH.
- Better tracing.
- Return DISP_E_EXCEPTION from ITypeInfo_Invoke on an error in the
  called function.
- Remove RegisterTypeLib hack.
- Support VT_BYREF|VT_I4 in _copy_arg.
- Activate ITypeLib, ITypeInfo and IEnumVARIANT Marshalers.
Alex Villacis Lasso <a_villacis@palosanto.com>
- Fix GIF palette allocation, by relying on ColorCount instead of
  SColorResolution.
- Ensure that underflowing negative float is represented as a positive
  0, just as native oleaut32.
Alexandre Julliard <julliard@winehq.org>
- Get rid of cursoricon.h.
Mike McCormack <mike@codeweavers.com>
- gcc 4.0 -Wpointer-sign fixes (Reg* functions).
- Interlocked LONG* gcc warning fixes.
Stefan Huehner <stefan@huehner.org>
- Fix some more -Wmissing-declarations warnings.
Robert Shearman <rob@codeweavers.com> for Mandriva
- Add a generic TYPEDESC VT to VARIANT VT mapper so we can use the
  standard Variant* routines. Use this new function to properly copy &
  de-reference the return value.
- Conversions between variants types of the same size should ignore
  overflows.
- Tests for this behaviour.

svn path=/trunk/; revision=17333

16 files changed:
reactos/include/wine/unicode.h
reactos/lib/oleaut32/connpt.c
reactos/lib/oleaut32/dispatch.c
reactos/lib/oleaut32/oleaut.c
reactos/lib/oleaut32/oleaut32.spec
reactos/lib/oleaut32/olefont.c
reactos/lib/oleaut32/olepicture.c
reactos/lib/oleaut32/recinfo.c
reactos/lib/oleaut32/regsvr.c
reactos/lib/oleaut32/tmarshal.c
reactos/lib/oleaut32/typelib.c
reactos/lib/oleaut32/typelib.h
reactos/lib/oleaut32/typelib16.c
reactos/lib/oleaut32/typelib2.c
reactos/lib/oleaut32/variant.c
reactos/lib/oleaut32/vartype.c

index c0e9f94..66453e7 100644 (file)
@@ -20,6 +20,7 @@
 #define strcmpiW(s1,s2) _wcsicmp((const wchar_t *)(s1),(const wchar_t *)(s2))
 #define strncmpiW(s1,s2,n) _wcsnicmp((const wchar_t *)(s1),(const wchar_t *)(s2),(n))
 #define strtoulW(s1,s2,b) wcstoul((const wchar_t *)(s1),(wchar_t **)(s2),(b))
+#define strspnW(str, accept) wcsspn((const wchar_t *)(str), (const wchar_t *)(accept))
 #define tolowerW(n) towlower((n))
 #define toupperW(n) towupper((n))
 #define islowerW(n) iswlower((n))
index f13bd67..da0ffcc 100644 (file)
@@ -54,7 +54,7 @@ typedef struct ConnectionPointImpl {
   IUnknown *Obj;
 
   /* Reference count */
-  DWORD ref;
+  LONG ref;
 
   /* IID of sink interface */
   IID iid;
@@ -76,7 +76,7 @@ typedef struct EnumConnectionsImpl {
 
   const IEnumConnectionsVtbl *lpvtbl;
 
-  DWORD ref;
+  LONG ref;
 
   /* IUnknown of ConnectionPoint, used for ref counting */
   IUnknown *pUnk;
index fd9d7b2..fbee4d8 100644 (file)
@@ -217,7 +217,7 @@ typedef struct
     const IDispatchVtbl *lpVtbl;
     void * pvThis;
     ITypeInfo * pTypeInfo;
-    ULONG ref;
+    LONG ref;
 } StdDispatch;
 
 /******************************************************************************
index 1527fed..b9125b4 100644 (file)
@@ -42,8 +42,11 @@ WINE_DEFAULT_DEBUG_CHANNEL(ole);
 /* The OLE Automation ProxyStub Interface Class (aka Typelib Marshaler) */
 extern const GUID CLSID_PSOAInterface;
 
-/* IDispatch marshaler */
 extern const GUID CLSID_PSDispatch;
+extern const GUID CLSID_PSEnumVariant;
+extern const GUID CLSID_PSTypeInfo;
+extern const GUID CLSID_PSTypeLib;
+extern const GUID CLSID_PSTypeComp;
 
 static BOOL BSTR_bCache = TRUE; /* Cache allocations to minimise alloc calls? */
 
@@ -449,6 +452,18 @@ static WCHAR       *pdelimiter = &_delimiter[0];
 
 /***********************************************************************
  *             RegisterActiveObject (OLEAUT32.33)
+ *
+ * Registers an object in the global item table.
+ *
+ * PARAMS
+ *  punk        [I] Object to register.
+ *  rcid        [I] CLSID of the object.
+ *  dwFlags     [I] Flags.
+ *  pdwRegister [O] Address to store cookie of object registration in.
+ *
+ * RETURNS
+ *  Success: S_OK.
+ *  Failure: HRESULT code.
  */
 HRESULT WINAPI RegisterActiveObject(
        LPUNKNOWN punk,REFCLSID rcid,DWORD dwFlags,LPDWORD pdwRegister
@@ -475,6 +490,16 @@ HRESULT WINAPI RegisterActiveObject(
 
 /***********************************************************************
  *             RevokeActiveObject (OLEAUT32.34)
+ *
+ * Revokes an object from the global item table.
+ *
+ * PARAMS
+ *  xregister [I] Registration cookie.
+ *  reserved  [I] Reserved. Set to NULL.
+ *
+ * RETURNS
+ *  Success: S_OK.
+ *  Failure: HRESULT code.
  */
 HRESULT WINAPI RevokeActiveObject(DWORD xregister,LPVOID reserved)
 {
@@ -491,6 +516,17 @@ HRESULT WINAPI RevokeActiveObject(DWORD xregister,LPVOID reserved)
 
 /***********************************************************************
  *             GetActiveObject (OLEAUT32.35)
+ *
+ * Gets an object from the global item table.
+ *
+ * PARAMS
+ *  rcid        [I] CLSID of the object.
+ *  preserved   [I] Reserved. Set to NULL.
+ *  ppunk       [O] Address to store object into.
+ *
+ * RETURNS
+ *  Success: S_OK.
+ *  Failure: HRESULT code.
  */
 HRESULT WINAPI GetActiveObject(REFCLSID rcid,LPVOID preserved,LPUNKNOWN *ppunk)
 {
@@ -667,7 +703,7 @@ extern void _get_STDPIC_CF(LPVOID);
 /***********************************************************************
  *             DllGetClassObject (OLEAUT32.1)
  */
-HRESULT WINAPI OLEAUT32_DllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv)
+HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv)
 {
     *ppv = NULL;
     if (IsEqualGUID(rclsid,&CLSID_StdFont)) {
@@ -684,8 +720,11 @@ HRESULT WINAPI OLEAUT32_DllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *p
            return S_OK;
        }
     }
-    if (IsEqualGUID(rclsid,&CLSID_PSDispatch)) {
-       return OLEAUTPS_DllGetClassObject(rclsid,iid,ppv);
+    if (IsEqualCLSID(rclsid, &CLSID_PSDispatch) ||
+        IsEqualCLSID(rclsid, &CLSID_PSTypeInfo) ||
+        IsEqualCLSID(rclsid, &CLSID_PSTypeLib) ||
+        IsEqualCLSID(rclsid, &CLSID_PSEnumVariant)) {
+        return OLEAUTPS_DllGetClassObject(&CLSID_PSDispatch, iid, ppv);
     }
     if (IsEqualGUID(rclsid,&CLSID_PSOAInterface)) {
        if (S_OK==TypeLibFac_DllGetClassObject(rclsid,iid,ppv))
@@ -707,7 +746,7 @@ HRESULT WINAPI OLEAUT32_DllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *p
  * RETURNS
  *  Always returns S_FALSE. This dll cannot be unloaded.
  */
-HRESULT WINAPI OLEAUT32_DllCanUnloadNow(void)
+HRESULT WINAPI DllCanUnloadNow(void)
 {
     return S_FALSE;
 }
index c49de81..2be07f6 100644 (file)
@@ -1,4 +1,4 @@
-1 stdcall -private DllGetClassObject(ptr ptr ptr) OLEAUT32_DllGetClassObject\r
+1 stdcall -private DllGetClassObject(ptr ptr ptr)\r
 2 stdcall SysAllocString(wstr)\r
 3 stdcall SysReAllocString(ptr wstr)\r
 4 stdcall SysAllocStringLen(wstr long)\r
 317 stdcall VarR8Round(double long ptr)\r
 318 stdcall VarCat(ptr ptr ptr)\r
 319 stdcall VarDateFromUdateEx(ptr long long ptr)\r
-320 stdcall -private DllRegisterServer() OLEAUT32_DllRegisterServer\r
-321 stdcall -private DllUnregisterServer() OLEAUT32_DllUnregisterServer\r
+320 stdcall -private DllRegisterServer()\r
+321 stdcall -private DllUnregisterServer()\r
 322 stdcall GetRecordInfoFromGuids(ptr long long long ptr ptr)\r
 323 stdcall GetRecordInfoFromTypeInfo(ptr ptr)\r
 325 stub SetVarConversionLocaleSetting\r
 399 stub UserMSG_free_local\r
 401 stdcall OleLoadPictureEx(ptr long long long long long long ptr)\r
 402 stub OleLoadPictureFileEx\r
-410 stdcall -private DllCanUnloadNow() OLEAUT32_DllCanUnloadNow\r
+410 stdcall -private DllCanUnloadNow()\r
 411 stdcall SafeArrayCreateVector(long long long)\r
 412 stdcall SafeArrayCopyData(ptr ptr)\r
 413 stdcall VectorFromBstr(ptr ptr)\r
index 2e6395a..0fce581 100644 (file)
@@ -72,7 +72,7 @@ struct OLEFontImpl
   /*
    * Reference count for that instance of the class.
    */
-  ULONG ref;
+  LONG ref;
 
   /*
    * This structure contains the description of the class.
@@ -2102,7 +2102,7 @@ typedef struct
 {
     /* IUnknown fields */
     const IClassFactoryVtbl    *lpVtbl;
-    DWORD                       ref;
+    LONG                        ref;
 } IClassFactoryImpl;
 
 static HRESULT WINAPI
index 6d40403..171ee03 100644 (file)
@@ -76,7 +76,6 @@
 #include "wine/unicode.h"
 
 #include "wine/wingdi16.h"
-#include "cursoricon.h"
 
 #ifdef HAVE_JPEGLIB_H
 /* This is a hack, so jpeglib.h does not redefine INT32 and the like*/
 
 WINE_DEFAULT_DEBUG_CHANNEL(ole);
 
+#include "pshpack1.h"
+
+typedef struct {
+    BYTE bWidth;
+    BYTE bHeight;
+    BYTE bColorCount;
+    BYTE bReserved;
+    WORD xHotspot;
+    WORD yHotspot;
+    DWORD dwDIBSize;
+    DWORD dwDIBOffset;
+} CURSORICONFILEDIRENTRY;
+
+typedef struct
+{
+    WORD                idReserved;
+    WORD                idType;
+    WORD                idCount;
+    CURSORICONFILEDIRENTRY  idEntries[1];
+} CURSORICONFILEDIR;
+
+#include "poppack.h"
+
 /*************************************************************************
  *  Declaration of implementation class
  */
@@ -109,7 +131,7 @@ typedef struct OLEPictureImpl {
     const IConnectionPointContainerVtbl *lpvtbl4;
 
   /* Object reference count */
-    DWORD ref;
+    LONG ref;
 
   /* We own the object and must destroy it ourselves */
     BOOL fOwn;
@@ -1117,12 +1139,12 @@ static HRESULT WINAPI OLEPictureImpl_Load(IPersistStream* iface,IStream*pStm) {
     );
     /* */
     padding = (gif->SWidth+3) & ~3;
-    bmi  = HeapAlloc(GetProcessHeap(),0,sizeof(BITMAPINFOHEADER)+(1<<gif->SColorResolution)*sizeof(RGBQUAD));
-    bytes= HeapAlloc(GetProcessHeap(),0,padding*gif->SHeight);
     si   = gif->SavedImages+0;
     gid  = &(si->ImageDesc);
     cm   = gid->ColorMap;
     if (!cm) cm = gif->SColorMap;
+    bmi  = HeapAlloc(GetProcessHeap(),0,sizeof(BITMAPINFOHEADER)+(cm->ColorCount)*sizeof(RGBQUAD));
+    bytes= HeapAlloc(GetProcessHeap(),0,padding*gif->SHeight);
     
     /* look for the transparent color extension */
     for (i = 0; i < si->ExtensionBlockCount; ++i) {
@@ -1134,7 +1156,7 @@ static HRESULT WINAPI OLEPictureImpl_Load(IPersistStream* iface,IStream*pStm) {
        }
     }
 
-    for (i=0;i<(1<<gif->SColorResolution);i++) {
+    for (i = 0; i < cm->ColorCount; 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;
@@ -1181,7 +1203,7 @@ static HRESULT WINAPI OLEPictureImpl_Load(IPersistStream* iface,IStream*pStm) {
     bmi->bmiHeader.biSizeImage         = padding*gif->SHeight;
     bmi->bmiHeader.biXPelsPerMeter     = 0;
     bmi->bmiHeader.biYPelsPerMeter     = 0;
-    bmi->bmiHeader.biClrUsed           = 1 << gif->SColorResolution;
+    bmi->bmiHeader.biClrUsed           = cm->ColorCount;
     bmi->bmiHeader.biClrImportant      = 0;
 
     hdcref = GetDC(0);
@@ -2210,7 +2232,7 @@ typedef struct
 {
     /* IUnknown fields */
     const IClassFactoryVtbl    *lpVtbl;
-    DWORD                       ref;
+    LONG                        ref;
 } IClassFactoryImpl;
 
 static HRESULT WINAPI
index 2ed6667..47c8bd7 100644 (file)
@@ -42,7 +42,7 @@ typedef struct {
 
 typedef struct {
     const IRecordInfoVtbl *lpVtbl;
-    ULONG ref;
+    LONG ref;
 
     GUID guid;
     UINT lib_index;
index 03c472e..daa9d55 100644 (file)
@@ -445,20 +445,20 @@ static GUID const CLSID_RecordInfo = {
 
 extern GUID const CLSID_PSDispatch;
 
-static GUID const CLSID_PSEnumVariant = {
+GUID const CLSID_PSEnumVariant = {
     0x00020421, 0x0000, 0x0000, {0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46} };
 
-static GUID const CLSID_PSTypeInfo = {
+GUID const CLSID_PSTypeInfo = {
     0x00020422, 0x0000, 0x0000, {0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46} };
 
-static GUID const CLSID_PSTypeLib = {
+GUID const CLSID_PSTypeLib = {
     0x00020423, 0x0000, 0x0000, {0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46} };
 
-extern GUID const CLSID_PSOAInterface;
-
-static GUID const CLSID_PSTypeComp = {
+GUID const CLSID_PSTypeComp = {
     0x00020425, 0x0000, 0x0000, {0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46} };
 
+extern GUID const CLSID_PSOAInterface;
+
 static GUID const CLSID_OldFont = {
     0x46763EE0, 0xCAB2, 0x11CE, {0x8C,0x20,0x00,0xAA,0x00,0x51,0xE5,0xD4} };
 
@@ -903,7 +903,7 @@ static struct regsvr_interface const interface_list[] = {
 /***********************************************************************
  *             DllRegisterServer (OLEAUT32.320)
  */
-HRESULT WINAPI OLEAUT32_DllRegisterServer()
+HRESULT WINAPI DllRegisterServer(void)
 {
     HRESULT hr;
 
@@ -918,7 +918,7 @@ HRESULT WINAPI OLEAUT32_DllRegisterServer()
 /***********************************************************************
  *             DllUnregisterServer (OLEAUT32.321)
  */
-HRESULT WINAPI OLEAUT32_DllUnregisterServer()
+HRESULT WINAPI DllUnregisterServer(void)
 {
     HRESULT hr;
 
index 7960ee6..720dc74 100644 (file)
@@ -262,7 +262,8 @@ _get_typeinfo_for_iid(REFIID riid, ITypeInfo**ti) {
     char       tlguid[200],typelibkey[300],interfacekey[300],ver[100];
     char       tlfn[260];
     OLECHAR    tlfnW[260];
-    DWORD      tlguidlen, verlen, type, tlfnlen;
+    DWORD      tlguidlen, verlen, type;
+    LONG       tlfnlen;
     ITypeLib   *tl;
 
     sprintf( interfacekey, "Interface\\{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}\\Typelib",
@@ -277,14 +278,14 @@ _get_typeinfo_for_iid(REFIID riid, ITypeInfo**ti) {
     }
     type = (1<<REG_SZ);
     tlguidlen = sizeof(tlguid);
-    if (RegQueryValueExA(ikey,NULL,NULL,&type,tlguid,&tlguidlen)) {
+    if (RegQueryValueExA(ikey,NULL,NULL,&type,(LPBYTE)tlguid,&tlguidlen)) {
        ERR("Getting typelib guid failed.\n");
        RegCloseKey(ikey);
        return E_FAIL;
     }
     type = (1<<REG_SZ);
     verlen = sizeof(ver);
-    if (RegQueryValueExA(ikey,"Version",NULL,&type,ver,&verlen)) {
+    if (RegQueryValueExA(ikey,"Version",NULL,&type,(LPBYTE)ver,&verlen)) {
        ERR("Could not get version value?\n");
        RegCloseKey(ikey);
        return E_FAIL;
@@ -357,7 +358,7 @@ typedef struct _TMAsmProxy {
 typedef struct _TMProxyImpl {
     LPVOID                             *lpvtbl;
     const IRpcProxyBufferVtbl          *lpvtbl2;
-    ULONG                              ref;
+    LONG                               ref;
 
     TMAsmProxy                         *asmstubs;
     ITypeInfo*                         tinfo;
@@ -564,15 +565,18 @@ serialize_param(
         if (writeit) {
             /* ptr to ptr to magic widestring, basically */
             BSTR *bstr = (BSTR *) *arg;
+            DWORD len;
             if (!*bstr) {
                 /* -1 means "null string" which is equivalent to empty string */
-                DWORD fakelen = -1;     
-                xbuf_add(buf, (LPBYTE)&fakelen,4);
+                len = -1;     
+                hres = xbuf_add(buf, (LPBYTE)&len,sizeof(DWORD));
+               if (hres) return hres;
             } else {
-                /* BSTRs store the length behind the first character */
-                DWORD *len = ((DWORD *)(*bstr))-1;
-                hres = xbuf_add(buf, (LPBYTE) len, *len + 4);
-                if (hres) return hres;
+               len = *((DWORD*)*bstr-1)/sizeof(WCHAR);
+               hres = xbuf_add(buf,(LPBYTE)&len,sizeof(DWORD));
+               if (hres) return hres;
+               hres = xbuf_add(buf,(LPBYTE)*bstr,len * sizeof(WCHAR));
+               if (hres) return hres;
             }
         }
 
@@ -591,17 +595,18 @@ serialize_param(
                    TRACE_(olerelay)("<bstr NULL>");
        }
        if (writeit) {
-           if (!*arg) {
-               DWORD fakelen = -1;
-               hres = xbuf_add(buf,(LPBYTE)&fakelen,4);
-               if (hres)
-                   return hres;
+            BSTR bstr = (BSTR)*arg;
+            DWORD len;
+           if (!bstr) {
+               len = -1;
+               hres = xbuf_add(buf,(LPBYTE)&len,sizeof(DWORD));
+               if (hres) return hres;
            } else {
-               DWORD *bstr = ((DWORD*)(*arg))-1;
-
-               hres = xbuf_add(buf,(LPBYTE)bstr,bstr[0]+4);
-               if (hres)
-                   return hres;
+               len = *((DWORD*)bstr-1)/sizeof(WCHAR);
+               hres = xbuf_add(buf,(LPBYTE)&len,sizeof(DWORD));
+               if (hres) return hres;
+               hres = xbuf_add(buf,(LPBYTE)bstr,len * sizeof(WCHAR));
+               if (hres) return hres;
            }
        }
 
@@ -704,6 +709,14 @@ serialize_param(
            if (debugout) TRACE_(olerelay)("}");
            break;
        }
+       case TKIND_ALIAS:
+           return serialize_param(tinfo2,writeit,debugout,dealloc,&tattr->tdescAlias,arg,buf);
+       case TKIND_ENUM:
+           hres = S_OK;
+           if (debugout) TRACE_(olerelay)("%lx",*arg);
+           if (writeit)
+               hres = xbuf_add(buf,(LPBYTE)arg,sizeof(DWORD));
+           return hres;
        default:
            FIXME("Unhandled typekind %d\n",tattr->typekind);
            hres = E_FAIL;
@@ -1130,8 +1143,8 @@ deserialize_param(
                    **bstr = NULL;
                    if (debugout) TRACE_(olerelay)("<bstr NULL>");
                } else {
-                   str  = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,len+sizeof(WCHAR));
-                   hres = xbuf_get(buf,(LPBYTE)str,len);
+                   str  = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,(len+1)*sizeof(WCHAR));
+                   hres = xbuf_get(buf,(LPBYTE)str,len*sizeof(WCHAR));
                    if (hres) {
                        ERR("Failed to read BSTR.\n");
                        return hres;
@@ -1160,8 +1173,8 @@ deserialize_param(
                    *arg = 0;
                    if (debugout) TRACE_(olerelay)("<bstr NULL>");
                } else {
-                   str  = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,len+sizeof(WCHAR));
-                   hres = xbuf_get(buf,(LPBYTE)str,len);
+                   str  = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,(len+1)*sizeof(WCHAR));
+                   hres = xbuf_get(buf,(LPBYTE)str,len*sizeof(WCHAR));
                    if (hres) {
                        ERR("Failed to read BSTR.\n");
                        return hres;
@@ -1275,6 +1288,15 @@ deserialize_param(
                    if (debugout) TRACE_(olerelay)("}");
                    break;
                }
+               case TKIND_ALIAS:
+                   return deserialize_param(tinfo2,readit,debugout,alloc,&tattr->tdescAlias,arg,buf);
+               case TKIND_ENUM:
+                   if (readit) {
+                       hres = xbuf_get(buf,(LPBYTE)arg,sizeof(DWORD));
+                       if (hres) ERR("Failed to read enum (4 byte)\n");
+                   }
+                   if (debugout) TRACE_(olerelay)("%lx",*arg);
+                   return hres;
                default:
                    ERR("Unhandled typekind %d\n",tattr->typekind);
                    hres = E_FAIL;
@@ -1911,7 +1933,7 @@ PSFacBuf_CreateProxy(
 
 typedef struct _TMStubImpl {
     const IRpcStubBufferVtbl   *lpvtbl;
-    ULONG                      ref;
+    LONG                       ref;
 
     LPUNKNOWN                  pUnk;
     ITypeInfo                  *tinfo;
@@ -1952,6 +1974,7 @@ TMStubImpl_Release(LPRPCSTUBBUFFER iface)
     if (!refCount)
     {
         IRpcStubBuffer_Disconnect(iface);
+        ITypeInfo_Release(This->tinfo);
         CoTaskMemFree(This);
     }
     return refCount;
@@ -1976,9 +1999,11 @@ TMStubImpl_Disconnect(LPRPCSTUBBUFFER iface)
 
     TRACE("(%p)->()\n", This);
 
-    IUnknown_Release(This->pUnk);
-    This->pUnk = NULL;
-    return;
+    if (This->pUnk)
+    {
+        IUnknown_Release(This->pUnk);
+        This->pUnk = NULL;
+    }
 }
 
 static HRESULT WINAPI
index 869f90b..e49fa4a 100644 (file)
@@ -84,6 +84,8 @@ WINE_DECLARE_DEBUG_CHANNEL(typelib);
 /* The OLE Automation ProxyStub Interface Class (aka Typelib Marshaler) */
 const GUID CLSID_PSOAInterface = { 0x00020424, 0, 0, { 0xC0, 0, 0, 0, 0, 0, 0, 0x46 } };
 
+static HRESULT typedescvt_to_variantvt(ITypeInfo *tinfo, TYPEDESC *tdesc, VARTYPE *vt);
+
 /****************************************************************************
  *              FromLExxx
  *
@@ -617,17 +619,8 @@ HRESULT WINAPI RegisterTypeLib(
                        MESSAGE("\n");
                    }
 
-                   /*
-                    * FIXME: The 1 is just here until we implement rpcrt4
-                    *        stub/proxy handling. Until then it helps IShield
-                    *        v6 to work.
-                    */
-                   if (1 || (tattr->wTypeFlags & TYPEFLAG_FOLEAUTOMATION))
+                   if (tattr->wTypeFlags & (TYPEFLAG_FOLEAUTOMATION|TYPEFLAG_FDUAL))
                    {
-                        if (!(tattr->wTypeFlags & TYPEFLAG_FOLEAUTOMATION)) {
-                            FIXME("Registering non-oleautomation interface!\n");
-                        }
-
                        /* register interface<->typelib coupling */
                        get_interface_key( &tattr->guid, keyName );
                        if (RegCreateKeyExW(HKEY_CLASSES_ROOT, keyName, 0, NULL, 0,
@@ -863,7 +856,7 @@ typedef struct tagITypeLibImpl
 {
     const ITypeLib2Vtbl *lpVtbl;
     const ITypeCompVtbl *lpVtblTypeComp;
-    ULONG ref;
+    LONG ref;
     TLIBATTR LibAttr;            /* guid,lcid,syskind,version,flags */
 
     /* strings can be stored in tlb as multibyte strings BUT they are *always*
@@ -975,7 +968,7 @@ typedef struct tagITypeInfoImpl
 {
     const ITypeInfo2Vtbl *lpVtbl;
     const ITypeCompVtbl  *lpVtblTypeComp;
-    ULONG ref;
+    LONG ref;
     TYPEATTR TypeAttr ;         /* _lots_ of type information. */
     ITypeLibImpl * pTypeLib;        /* back pointer to typelib */
     int index;                  /* index in this typelib; */
@@ -1070,14 +1063,14 @@ static void dump_TypeDesc(TYPEDESC *pTD,char *szVarType) {
     }
 }
 
-void dump_ELEMDESC(ELEMDESC *edesc) {
+static void dump_ELEMDESC(ELEMDESC *edesc) {
   char buf[200];
   dump_TypeDesc(&edesc->tdesc,buf);
   MESSAGE("\t\ttdesc.vartype %d (%s)\n",edesc->tdesc.vt,buf);
   MESSAGE("\t\tu.parmadesc.flags %x\n",edesc->u.paramdesc.wParamFlags);
   MESSAGE("\t\tu.parmadesc.lpex %p\n",edesc->u.paramdesc.pparamdescex);
 }
-void dump_FUNCDESC(FUNCDESC *funcdesc) {
+static void dump_FUNCDESC(FUNCDESC *funcdesc) {
   int i;
   MESSAGE("memid is %08lx\n",funcdesc->memid);
   for (i=0;i<funcdesc->cParams;i++) {
@@ -1116,10 +1109,6 @@ void dump_FUNCDESC(FUNCDESC *funcdesc) {
   dump_ELEMDESC(&funcdesc->elemdescFunc);
 }
 
-void dump_IDLDESC(IDLDESC *idl) {
-  MESSAGE("\t\twIdlflags: %d\n",idl->wIDLFlags);
-}
-
 static const char * typekind_desc[] =
 {
        "TKIND_ENUM",
@@ -1133,27 +1122,6 @@ static const char * typekind_desc[] =
        "TKIND_MAX"
 };
 
-void dump_TYPEATTR(TYPEATTR *tattr) {
-  char buf[200];
-  MESSAGE("\tguid: %s\n",debugstr_guid(&tattr->guid));
-  MESSAGE("\tlcid: %ld\n",tattr->lcid);
-  MESSAGE("\tmemidConstructor: %ld\n",tattr->memidConstructor);
-  MESSAGE("\tmemidDestructor: %ld\n",tattr->memidDestructor);
-  MESSAGE("\tschema: %s\n",debugstr_w(tattr->lpstrSchema));
-  MESSAGE("\tsizeInstance: %ld\n",tattr->cbSizeInstance);
-  MESSAGE("\tkind:%s\n", typekind_desc[tattr->typekind]);
-  MESSAGE("\tcFuncs: %d\n", tattr->cFuncs);
-  MESSAGE("\tcVars: %d\n", tattr->cVars);
-  MESSAGE("\tcImplTypes: %d\n", tattr->cImplTypes);
-  MESSAGE("\tcbSizeVft: %d\n", tattr->cbSizeVft);
-  MESSAGE("\tcbAlignment: %d\n", tattr->cbAlignment);
-  MESSAGE("\twTypeFlags: %d\n", tattr->wTypeFlags);
-  MESSAGE("\tVernum: %d.%d\n", tattr->wMajorVerNum,tattr->wMinorVerNum);
-  dump_TypeDesc(&tattr->tdescAlias,buf);
-  MESSAGE("\ttypedesc: %s\n", buf);
-  dump_IDLDESC(&tattr->idldescType);
-}
-
 static void dump_TLBFuncDescOne(TLBFuncDesc * pfd)
 {
   int i;
@@ -1305,7 +1273,7 @@ static void dump_TypeInfo(ITypeInfoImpl * pty)
     dump_TLBImplType(pty->impltypelist);
 }
 
-void dump_VARDESC(VARDESC *v)
+static void dump_VARDESC(VARDESC *v)
 {
     MESSAGE("memid %ld\n",v->memid);
     MESSAGE("lpstrSchema %s\n",debugstr_w(v->lpstrSchema));
@@ -1397,7 +1365,7 @@ static void free_deep_typedesc(TYPEDESC *tdesc)
  *  Functions for reading MSFT typelibs (those created by CreateTypeLib2)
  */
 /* read function */
-DWORD MSFT_Read(void *buffer,  DWORD count, TLBContext *pcx, long where )
+static DWORD MSFT_Read(void *buffer,  DWORD count, TLBContext *pcx, long where )
 {
     TRACE_(typelib)("pos=0x%08x len=0x%08lx 0x%08x 0x%08x 0x%08lx\n",
        pcx->pos, count, pcx->oStart, pcx->length, where);
@@ -1454,7 +1422,7 @@ static void MSFT_ReadGuid( GUID *pGuid, int offset, TLBContext *pcx)
     TRACE_(typelib)("%s\n", debugstr_guid(pGuid));
 }
 
-BSTR MSFT_ReadName( TLBContext *pcx, int offset)
+static BSTR MSFT_ReadName( TLBContext *pcx, int offset)
 {
     char * name;
     MSFT_NameIntro niName;
@@ -1489,7 +1457,7 @@ BSTR MSFT_ReadName( TLBContext *pcx, int offset)
     return bstrName;
 }
 
-BSTR MSFT_ReadString( TLBContext *pcx, int offset)
+static BSTR MSFT_ReadString( TLBContext *pcx, int offset)
 {
     char * string;
     INT16 length;
@@ -1997,8 +1965,11 @@ static void MSFT_DoRefType(TLBContext *pcx, ITypeInfoImpl *pTI,
         if(pImpLib){
             (*ppRefType)->reference=offset;
             (*ppRefType)->pImpTLInfo = pImpLib;
-            MSFT_ReadGuid(&(*ppRefType)->guid, impinfo.oGuid, pcx);
-           (*ppRefType)->index = TLB_REF_USE_GUID;
+            if(impinfo.flags & MSFT_IMPINFO_OFFSET_IS_GUID) {
+                MSFT_ReadGuid(&(*ppRefType)->guid, impinfo.oGuid, pcx);
+                (*ppRefType)->index = TLB_REF_USE_GUID;
+            } else
+                (*ppRefType)->index = impinfo.oGuid;               
         }else{
             ERR("Cannot find a reference\n");
             (*ppRefType)->reference=-1;
@@ -2038,7 +2009,7 @@ static void MSFT_DoImplTypes(TLBContext *pcx, ITypeInfoImpl *pTI, int count,
 /*
  * process a typeinfo record
  */
-ITypeInfoImpl * MSFT_DoTypeInfo(
+static ITypeInfoImpl * MSFT_DoTypeInfo(
     TLBContext *pcx,
     int count,
     ITypeLibImpl * pLibInfo)
@@ -4617,6 +4588,10 @@ _copy_arg(       ITypeInfo2 *tinfo, TYPEDESC *tdesc,
              memcpy(argpos, &V_I4(arg), 4);
              hres = S_OK;
              break;
+          case VT_BYREF|VT_I4:
+             memcpy(argpos, V_I4REF(arg), 4);
+             hres = S_OK;
+             break;
           default:
              FIXME("vt 0x%x -> TKIND_ENUM unhandled.\n",V_VT(arg));
              hres = E_FAIL;
@@ -4697,6 +4672,123 @@ _copy_arg(      ITypeInfo2 *tinfo, TYPEDESC *tdesc,
     return E_FAIL;
 }
 
+static HRESULT userdefined_to_variantvt(ITypeInfo *tinfo, TYPEDESC *tdesc, VARTYPE *vt)
+{
+    HRESULT hr = S_OK;
+    ITypeInfo *tinfo2 = NULL;
+    TYPEATTR *tattr = NULL;
+
+    hr = ITypeInfo_GetRefTypeInfo(tinfo, tdesc->u.hreftype, &tinfo2);
+    if (hr)
+    {
+        ERR("Could not get typeinfo of hreftype %lx for VT_USERDEFINED, "
+            "hr = 0x%08lx\n",
+              tdesc->u.hreftype, hr);
+        return hr;
+    }
+    hr = ITypeInfo_GetTypeAttr(tinfo2, &tattr);
+    if (hr)
+    {
+        ERR("ITypeInfo_GetTypeAttr failed, hr = 0x%08lx\n", hr);
+        ITypeInfo_Release(tinfo2);
+        return hr;
+    }
+
+    switch (tattr->typekind)
+    {
+    case TKIND_ENUM:
+        *vt |= VT_INT;
+        break;
+
+    case TKIND_ALIAS:
+        tdesc = &tattr->tdescAlias;
+        hr = typedescvt_to_variantvt(tinfo2, &tattr->tdescAlias, vt);
+        break;
+
+    case TKIND_INTERFACE:
+       if (IsEqualIID(&IID_IDispatch, &tattr->guid))
+          *vt |= VT_DISPATCH;
+               else
+                  *vt |= VT_UNKNOWN;
+               break;
+
+    case TKIND_DISPATCH:
+        *vt |= VT_DISPATCH;
+        break;
+
+    case TKIND_RECORD:
+        FIXME("TKIND_RECORD unhandled.\n");
+        hr = E_NOTIMPL;
+        break;
+
+    case TKIND_UNION:
+        FIXME("TKIND_RECORD unhandled.\n");
+        hr = E_NOTIMPL;
+        break;
+
+    default:
+        FIXME("TKIND %d unhandled.\n",tattr->typekind);
+        hr = E_NOTIMPL;
+        break;
+    }
+    ITypeInfo_ReleaseTypeAttr(tinfo2, tattr);
+    ITypeInfo_Release(tinfo2);
+    return hr;
+}
+
+static HRESULT typedescvt_to_variantvt(ITypeInfo *tinfo, TYPEDESC *tdesc, VARTYPE *vt)
+{
+    HRESULT hr = S_OK;
+
+    /* enforce only one level of pointer indirection */
+    if (!(*vt & VT_BYREF) && (tdesc->vt == VT_PTR))
+    {
+        tdesc = tdesc->u.lptdesc;
+
+        /* munch VT_PTR -> VT_USERDEFINED(interface) into VT_UNKNOWN or
+         * VT_DISPATCH and VT_PTR -> VT_PTR -> VT_USERDEFINED(interface) into 
+         * VT_BYREF|VT_DISPATCH or VT_BYREF|VT_UNKNOWN */
+        if ((tdesc->vt == VT_USERDEFINED) ||
+            ((tdesc->vt == VT_PTR) && (tdesc->u.lptdesc->vt == VT_USERDEFINED)))
+        {
+            VARTYPE vt_userdefined = 0;
+            TYPEDESC *tdesc_userdefined = tdesc;
+            if (tdesc->vt == VT_PTR)
+            {
+                vt_userdefined = VT_BYREF;
+                tdesc_userdefined = tdesc->u.lptdesc;
+            }
+            hr = userdefined_to_variantvt(tinfo, tdesc_userdefined, &vt_userdefined);
+            if ((hr == S_OK) && 
+                (((vt_userdefined & VT_TYPEMASK) == VT_UNKNOWN) ||
+                 ((vt_userdefined & VT_TYPEMASK) == VT_DISPATCH)))
+            {
+                *vt |= vt_userdefined;
+                return S_OK;
+            }
+        }
+        *vt = VT_BYREF;
+    }
+
+    switch (tdesc->vt)
+    {
+    case VT_HRESULT:
+        *vt |= VT_ERROR;
+        break;
+    case VT_USERDEFINED:
+        hr = userdefined_to_variantvt(tinfo, tdesc, vt);
+        break;
+    case VT_PTR:
+        ERR("cannot convert VT_PTR into variant VT\n");
+        hr = E_FAIL;
+        break;
+    default:
+        *vt |= tdesc->vt;
+        break;
+    }
+    return hr;
+}
+
 /***********************************************************************
  *             DispCallFunc (OLEAUT32.@)
  */
@@ -4772,6 +4864,11 @@ static HRESULT WINAPI ITypeInfo_fnInvoke(
 
         hres = ITypeInfo2_GetFuncDesc(iface, func_index, &func_desc);
         if(FAILED(hres)) return hres;
+        if (TRACE_ON(ole))
+        {
+            TRACE("invoking:\n");
+            dump_FUNCDESC(func_desc);
+        }
         
        switch (func_desc->funckind) {
        case FUNC_PUREVIRTUAL:
@@ -4873,76 +4970,36 @@ static HRESULT WINAPI ITypeInfo_fnInvoke(
                    args
            );
 
-           if (pVarResult && (dwFlags & (DISPATCH_PROPERTYGET))) {
-               args2pos = 0;
-               for (i = 0; i < func_desc->cParams - pDispParams->cArgs; i++) {
-                   ELEMDESC *elemdesc = &(func_desc->lprgelemdescParam[i+pDispParams->cArgs]);
-                   TYPEDESC *tdesc = &(elemdesc->tdesc);
-                   int arglen = _argsize(tdesc->vt);
-                   TYPEDESC i4_tdesc;
-                   i4_tdesc.vt = VT_I4;
-
-                   /* If we are a pointer to a variant, we are done already */
-                   if ((tdesc->vt==VT_PTR)&&(tdesc->u.lptdesc->vt==VT_VARIANT))
-                       continue;
-
-                   if (tdesc->vt == VT_PTR) {
-                       tdesc = tdesc->u.lptdesc;
-                       arglen = _argsize(tdesc->vt);
-                   }
-
-                   VariantInit(pVarResult);
-                   memcpy(&V_INT(pVarResult),&args2[args2pos],arglen*sizeof(DWORD));
-
-                   if (tdesc->vt == VT_USERDEFINED) {
-                       ITypeInfo       *tinfo2;
-                       TYPEATTR        *tattr;
-
-                       hres = ITypeInfo_GetRefTypeInfo(iface,tdesc->u.hreftype,&tinfo2);
-                       if (FAILED(hres)) {
-                           FIXME("Could not get typeinfo of hreftype %lx for VT_USERDEFINED, while coercing. Copying 4 byte.\n",tdesc->u.hreftype);
-                           goto func_fail;
-                       }
-                       ITypeInfo_GetTypeAttr(tinfo2,&tattr);
-                       switch (tattr->typekind) {
-                       case TKIND_ENUM:
-                            /* force the return type to be VT_I4 */
-                            tdesc = &i4_tdesc;
+           if (pVarResult) {
+               for (i = 0; i < func_desc->cParams; i++) {
+                    USHORT wParamFlags = func_desc->lprgelemdescParam[i].u.paramdesc.wParamFlags;
+                    if (wParamFlags & PARAMFLAG_FRETVAL) {
+                        ELEMDESC *elemdesc = &func_desc->lprgelemdescParam[i];
+                        TYPEDESC *tdesc = &elemdesc->tdesc;
+                        VARIANTARG varresult;
+                        V_VT(&varresult) = 0;
+                        hres = typedescvt_to_variantvt((ITypeInfo *)iface, tdesc, &V_VT(&varresult));
+                        if (hres)
                             break;
-                       case TKIND_ALIAS:
-                           TRACE("TKIND_ALIAS to vt 0x%x\n",tattr->tdescAlias.vt);
-                           tdesc = &(tattr->tdescAlias);
-                           break;
-
-                       case TKIND_INTERFACE:
-                           FIXME("TKIND_INTERFACE unhandled.\n");
-                           break;
-                       case TKIND_DISPATCH:
-                           FIXME("TKIND_DISPATCH unhandled.\n");
-                           break;
-                       case TKIND_RECORD:
-                           FIXME("TKIND_RECORD unhandled.\n");
-                           break;
-                       default:
-                           FIXME("TKIND %d unhandled.\n",tattr->typekind);
-                           break;
-                       }
-                       ITypeInfo_Release(tinfo2);
+                        /* FIXME: this is really messy - we should keep the
+                         * args in VARIANTARGs rather than a DWORD array */
+                        memcpy(&V_UI4(&varresult), &args[i+1], sizeof(DWORD));
+                        if (TRACE_ON(ole))
+                        {
+                            TRACE("varresult: ");
+                            dump_Variant(&varresult);
+                        }
+                        hres = VariantCopyInd(pVarResult, &varresult);
+                        break;
                    }
-                   V_VT(pVarResult) = tdesc->vt;
-
-                   /* HACK: VB5 likes this.
-                    * I do not know why. There is 1 example in MSDN which uses
-                    * this which appears broken (mixes int vals and
-                    * IDispatch*.).
-                    */
-                   if ((tdesc->vt == VT_PTR) && (dwFlags & DISPATCH_METHOD))
-                       V_VT(pVarResult) = VT_DISPATCH;
-                   TRACE("storing into variant:\n");
-                   dump_Variant(pVarResult);
-                   args2pos += arglen;
                }
            }
+
+           if ((func_desc->elemdescFunc.tdesc.vt == VT_HRESULT) && FAILED(res)) {
+               WARN("invoked function failed with error 0x%08lx\n", res);
+               hres = DISP_E_EXCEPTION;
+               if (pExcepInfo) pExcepInfo->scode = res;
+           }
 func_fail:
             HeapFree(GetProcessHeap(), 0, rgvarg);
            HeapFree(GetProcessHeap(),0,args2);
index 6f7b8cd..5e9c90f 100644 (file)
@@ -157,17 +157,19 @@ typedef struct tagMSFT_TypeInfoBase {
                                 /* else it is zero? */
         INT     res18;          /* always? 0 */
 /*060*/ INT     res19;          /* always? -1 */
-    } MSFT_TypeInfoBase;
+} MSFT_TypeInfoBase;
 
 /* layout of an entry with information on imported types */
 typedef struct tagMSFT_ImpInfo {
-    INT     res0;           /* bits 0 - 15:  count */
+    INT     flags;          /* bits 0 - 15:  count */
                             /* bit  16:      if set oGuid is an offset to Guid */
                             /*               if clear oGuid is a typeinfo index in the specified typelib */
                             /* bits 24 - 31: TKIND of reference */
     INT     oImpFile;       /* offset in the Import File table */
     INT     oGuid;          /* offset in Guid table or typeinfo index (see bit 16 of res0) */
-    } MSFT_ImpInfo;
+} MSFT_ImpInfo;
+
+#define MSFT_IMPINFO_OFFSET_IS_GUID 0x00010000
 
 /* function description data */
 typedef struct {
index 01abb2d..aedb499 100644 (file)
@@ -80,7 +80,7 @@ QueryPathOfRegTypeLib16(
 {
        char    xguid[80];
        char    typelibkey[100],pathname[260];
-       DWORD   plen;
+       LONG    plen;
 
                TRACE("\n");
 
index 14d9112..ffc5b88 100644 (file)
@@ -148,7 +148,7 @@ typedef struct tagICreateTypeLib2Impl
     const ICreateTypeLib2Vtbl *lpVtbl;
     const ITypeLib2Vtbl       *lpVtblTypeLib2;
 
-    ULONG ref;
+    LONG ref;
 
     WCHAR *filename;
 
@@ -174,7 +174,7 @@ typedef struct tagICreateTypeInfo2Impl
     const ICreateTypeInfo2Vtbl *lpVtbl;
     const ITypeInfo2Vtbl       *lpVtblTypeInfo2;
 
-    ULONG ref;
+    LONG ref;
 
     ICreateTypeLib2Impl *typelib;
     MSFT_TypeInfoBase *typeinfo;
@@ -1242,7 +1242,7 @@ static HRESULT WINAPI ICreateTypeInfo2_fnSetTypeFlags(ICreateTypeInfo2 *iface, U
        guidoffset = ctl2_alloc_guid(This->typelib, &foo);
        if (guidoffset == -1) return E_OUTOFMEMORY;
 
-       impinfo.res0 = 0x03010000;
+       impinfo.flags = TKIND_INTERFACE << 24 | MSFT_IMPINFO_OFFSET_IS_GUID;
        impinfo.oImpFile = fileoffset;
        impinfo.oGuid = guidoffset;
        ctl2_alloc_importinfo(This->typelib, &impinfo);
index 4a9985a..0a80e76 100644 (file)
@@ -82,7 +82,6 @@ static inline HRESULT VARIANT_Coerce(VARIANTARG* pd, LCID lcid, USHORT wFlags,
 {
   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),
@@ -117,11 +116,7 @@ static inline HRESULT VARIANT_Coerce(VARIANTARG* pd, LCID lcid, USHORT wFlags,
   if (vtFrom == VT_INT)
     vtFrom = VT_I4;
   else if (vtFrom == VT_UINT)
-  {
     vtFrom = VT_UI4;
-    if (vt == VT_I4)
-      bIgnoreOverflow = TRUE;
-  }
 
   if (vt == vtFrom)
      return VariantCopy(pd, ps);
@@ -155,7 +150,7 @@ static inline HRESULT VARIANT_Coerce(VARIANTARG* pd, LCID lcid, USHORT wFlags,
     case VT_EMPTY:    V_I1(pd) = 0; return S_OK;
     case VT_I2:       return VarI1FromI2(V_I2(ps), &V_I1(pd));
     case VT_I4:       return VarI1FromI4(V_I4(ps), &V_I1(pd));
-    case VT_UI1:      return VarI1FromUI1(V_UI1(ps), &V_I1(pd));
+    case VT_UI1:      V_I1(pd) = V_UI1(ps); return S_OK;
     case VT_UI2:      return VarI1FromUI2(V_UI2(ps), &V_I1(pd));
     case VT_UI4:      return VarI1FromUI4(V_UI4(ps), &V_I1(pd));
     case VT_I8:       return VarI1FromI8(V_I8(ps), &V_I1(pd));
@@ -178,7 +173,7 @@ static inline HRESULT VARIANT_Coerce(VARIANTARG* pd, LCID lcid, USHORT wFlags,
     case VT_I1:       return VarI2FromI1(V_I1(ps), &V_I2(pd));
     case VT_I4:       return VarI2FromI4(V_I4(ps), &V_I2(pd));
     case VT_UI1:      return VarI2FromUI1(V_UI1(ps), &V_I2(pd));
-    case VT_UI2:      return VarI2FromUI2(V_UI2(ps), &V_I2(pd));
+    case VT_UI2:      V_I2(pd) = V_UI2(ps); return S_OK;
     case VT_UI4:      return VarI2FromUI4(V_UI4(ps), &V_I2(pd));
     case VT_I8:       return VarI2FromI8(V_I8(ps), &V_I2(pd));
     case VT_UI8:      return VarI2FromUI8(V_UI8(ps), &V_I2(pd));
@@ -201,14 +196,7 @@ static inline HRESULT VARIANT_Coerce(VARIANTARG* pd, LCID lcid, USHORT wFlags,
     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:      
-          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_UI4:      V_I4(pd) = V_UI4(ps); return S_OK;
     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));
@@ -226,7 +214,7 @@ static inline HRESULT VARIANT_Coerce(VARIANTARG* pd, LCID lcid, USHORT wFlags,
     switch (vtFrom)
     {
     case VT_EMPTY:    V_UI1(pd) = 0; return S_OK;
-    case VT_I1:       return VarUI1FromI1(V_I1(ps), &V_UI1(pd));
+    case VT_I1:       V_UI1(pd) = V_I1(ps); return S_OK;
     case VT_I2:       return VarUI1FromI2(V_I2(ps), &V_UI1(pd));
     case VT_I4:       return VarUI1FromI4(V_I4(ps), &V_UI1(pd));
     case VT_UI2:      return VarUI1FromUI2(V_UI2(ps), &V_UI1(pd));
@@ -249,7 +237,7 @@ static inline HRESULT VARIANT_Coerce(VARIANTARG* pd, LCID lcid, USHORT wFlags,
     {
     case VT_EMPTY:    V_UI2(pd) = 0; return S_OK;
     case VT_I1:       return VarUI2FromI1(V_I1(ps), &V_UI2(pd));
-    case VT_I2:       return VarUI2FromI2(V_I2(ps), &V_UI2(pd));
+    case VT_I2:       V_UI2(pd) = V_I2(ps); return S_OK;
     case VT_I4:       return VarUI2FromI4(V_I4(ps), &V_UI2(pd));
     case VT_UI1:      return VarUI2FromUI1(V_UI1(ps), &V_UI2(pd));
     case VT_UI4:      return VarUI2FromUI4(V_UI4(ps), &V_UI2(pd));
@@ -272,7 +260,7 @@ static inline HRESULT VARIANT_Coerce(VARIANTARG* pd, LCID lcid, USHORT wFlags,
     case VT_EMPTY:    V_UI4(pd) = 0; return S_OK;
     case VT_I1:       return VarUI4FromI1(V_I1(ps), &V_UI4(pd));
     case VT_I2:       return VarUI4FromI2(V_I2(ps), &V_UI4(pd));
-    case VT_I4:       return VarUI4FromI4(V_I4(ps), &V_UI4(pd));
+    case VT_I4:       V_UI4(pd) = V_I4(ps); return S_OK;
     case VT_UI1:      return VarUI4FromUI1(V_UI1(ps), &V_UI4(pd));
     case VT_UI2:      return VarUI4FromUI2(V_UI2(ps), &V_UI4(pd));
     case VT_I8:       return VarUI4FromI8(V_I8(ps), &V_UI4(pd));
@@ -298,7 +286,7 @@ static inline HRESULT VARIANT_Coerce(VARIANTARG* pd, LCID lcid, USHORT wFlags,
     case VT_UI1:      return VarUI8FromUI1(V_UI1(ps), &V_UI8(pd));
     case VT_UI2:      return VarUI8FromUI2(V_UI2(ps), &V_UI8(pd));
     case VT_UI4:      return VarUI8FromUI4(V_UI4(ps), &V_UI8(pd));
-    case VT_I8:       return VarUI8FromI8(V_I8(ps), &V_UI8(pd));
+    case VT_I8:       V_UI8(pd) = V_I8(ps); return S_OK;
     case VT_R4:       return VarUI8FromR4(V_R4(ps), &V_UI8(pd));
     case VT_R8:       return VarUI8FromR8(V_R8(ps), &V_UI8(pd));
     case VT_DATE:     return VarUI8FromDate(V_DATE(ps), &V_UI8(pd));
@@ -320,7 +308,7 @@ static inline HRESULT VARIANT_Coerce(VARIANTARG* pd, LCID lcid, USHORT wFlags,
     case VT_UI1:      return VarI8FromUI1(V_UI1(ps), &V_I8(pd));
     case VT_UI2:      return VarI8FromUI2(V_UI2(ps), &V_I8(pd));
     case VT_UI4:      return VarI8FromUI4(V_UI4(ps), &V_I8(pd));
-    case VT_UI8:      return VarI8FromUI8(V_I8(ps), &V_I8(pd));
+    case VT_UI8:      V_I8(pd) = V_UI8(ps); return S_OK;
     case VT_R4:       return VarI8FromR4(V_R4(ps), &V_I8(pd));
     case VT_R8:       return VarI8FromR8(V_R8(ps), &V_I8(pd));
     case VT_DATE:     return VarI8FromDate(V_DATE(ps), &V_I8(pd));
@@ -2443,6 +2431,17 @@ VarNumFromParseNum_DecOverflow:
 
 /**********************************************************************
  *              VarCat [OLEAUT32.318]
+ *
+ * Concatenates one variant onto another.
+ *
+ * PARAMS
+ *  left    [I] First variant
+ *  right   [I] Second variant
+ *  result  [O] Result variant
+ *
+ * RETURNS
+ *  Success: S_OK.
+ *  Failure: An HRESULT error code indicating the error.
  */
 HRESULT WINAPI VarCat(LPVARIANT left, LPVARIANT right, LPVARIANT out)
 {
@@ -2638,6 +2637,16 @@ HRESULT WINAPI VarCmp(LPVARIANT left, LPVARIANT right, LCID lcid, DWORD flags)
 /**********************************************************************
  *              VarAnd [OLEAUT32.142]
  *
+ * Computes the logical AND of two variants.
+ *
+ * PARAMS
+ *  left    [I] First variant
+ *  right   [I] Second variant
+ *  result  [O] Result variant
+ *
+ * RETURNS
+ *  Success: S_OK.
+ *  Failure: An HRESULT error code indicating the error.
  */
 HRESULT WINAPI VarAnd(LPVARIANT left, LPVARIANT right, LPVARIANT result)
 {
@@ -3073,6 +3082,16 @@ end:
 /**********************************************************************
  *              VarDiv [OLEAUT32.143]
  *
+ * Divides one variant with another.
+ *
+ * PARAMS
+ *  left    [I] First variant
+ *  right   [I] Second variant
+ *  result  [O] Result variant
+ *
+ * RETURNS
+ *  Success: S_OK.
+ *  Failure: An HRESULT error code indicating the error.
  */
 HRESULT WINAPI VarDiv(LPVARIANT left, LPVARIANT right, LPVARIANT result)
 {
@@ -3132,6 +3151,16 @@ HRESULT WINAPI VarDiv(LPVARIANT left, LPVARIANT right, LPVARIANT result)
 /**********************************************************************
  *              VarSub [OLEAUT32.159]
  *
+ * Subtract two variants.
+ *
+ * PARAMS
+ *  left    [I] First variant
+ *  right   [I] Second variant
+ *  result  [O] Result variant
+ *
+ * RETURNS
+ *  Success: S_OK.
+ *  Failure: An HRESULT error code indicating the error.
  */
 HRESULT WINAPI VarSub(LPVARIANT left, LPVARIANT right, LPVARIANT result)
 {
@@ -4528,6 +4557,16 @@ HRESULT WINAPI VarMod(LPVARIANT left, LPVARIANT right, LPVARIANT result)
 /**********************************************************************
  *              VarPow [OLEAUT32.158]
  *
+ * Computes the power of one variant to another variant.
+ *
+ * PARAMS
+ *  left    [I] First variant
+ *  right   [I] Second variant
+ *  result  [O] Result variant
+ *
+ * RETURNS
+ *  Success: S_OK.
+ *  Failure: An HRESULT error code indicating the error.
  */
 HRESULT WINAPI VarPow(LPVARIANT left, LPVARIANT right, LPVARIANT result)
 {
index a82b692..0e1b7e8 100644 (file)
@@ -5258,6 +5258,19 @@ static HRESULT VARIANT_BstrFromReal(DOUBLE dblIn, LCID lcid, ULONG dwFlags,
     return E_INVALIDARG;
 
   sprintfW( buff, lpszFormat, dblIn );
+
+  /* Negative zeroes are disallowed (some applications depend on this).
+     If buff starts with a minus, and then nothing follows but zeroes
+     and/or a period, it is a negative zero and is replaced with a
+     canonical zero. This duplicates native oleaut32 behavior.
+   */
+  if (buff[0] == '-')
+  {
+    const WCHAR szAccept[] = {'0', '.', '\0'};
+    if (strlenW(buff + 1) == strspnW(buff + 1, szAccept))
+    { buff[0] = '0'; buff[1] = '\0'; }
+  }
+
   TRACE("created string %s\n", debugstr_w(buff));
   if (dwFlags & LOCALE_USE_NLS)
   {