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 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))
 #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 */
   IUnknown *Obj;
 
   /* Reference count */
-  DWORD ref;
+  LONG ref;
 
   /* IID of sink interface */
   IID iid;
 
   /* IID of sink interface */
   IID iid;
@@ -76,7 +76,7 @@ typedef struct EnumConnectionsImpl {
 
   const IEnumConnectionsVtbl *lpvtbl;
 
 
   const IEnumConnectionsVtbl *lpvtbl;
 
-  DWORD ref;
+  LONG ref;
 
   /* IUnknown of ConnectionPoint, used for ref counting */
   IUnknown *pUnk;
 
   /* 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;
     const IDispatchVtbl *lpVtbl;
     void * pvThis;
     ITypeInfo * pTypeInfo;
-    ULONG ref;
+    LONG ref;
 } StdDispatch;
 
 /******************************************************************************
 } 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;
 
 /* 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_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? */
 
 
 static BOOL BSTR_bCache = TRUE; /* Cache allocations to minimise alloc calls? */
 
@@ -449,6 +452,18 @@ static WCHAR       *pdelimiter = &_delimiter[0];
 
 /***********************************************************************
  *             RegisterActiveObject (OLEAUT32.33)
 
 /***********************************************************************
  *             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
  */
 HRESULT WINAPI RegisterActiveObject(
        LPUNKNOWN punk,REFCLSID rcid,DWORD dwFlags,LPDWORD pdwRegister
@@ -475,6 +490,16 @@ HRESULT WINAPI RegisterActiveObject(
 
 /***********************************************************************
  *             RevokeActiveObject (OLEAUT32.34)
 
 /***********************************************************************
  *             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)
 {
  */
 HRESULT WINAPI RevokeActiveObject(DWORD xregister,LPVOID reserved)
 {
@@ -491,6 +516,17 @@ HRESULT WINAPI RevokeActiveObject(DWORD xregister,LPVOID reserved)
 
 /***********************************************************************
  *             GetActiveObject (OLEAUT32.35)
 
 /***********************************************************************
  *             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)
 {
  */
 HRESULT WINAPI GetActiveObject(REFCLSID rcid,LPVOID preserved,LPUNKNOWN *ppunk)
 {
@@ -667,7 +703,7 @@ extern void _get_STDPIC_CF(LPVOID);
 /***********************************************************************
  *             DllGetClassObject (OLEAUT32.1)
  */
 /***********************************************************************
  *             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)) {
 {
     *ppv = NULL;
     if (IsEqualGUID(rclsid,&CLSID_StdFont)) {
@@ -684,8 +720,11 @@ HRESULT WINAPI OLEAUT32_DllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *p
            return S_OK;
        }
     }
            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))
     }
     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.
  */
  * RETURNS
  *  Always returns S_FALSE. This dll cannot be unloaded.
  */
-HRESULT WINAPI OLEAUT32_DllCanUnloadNow(void)
+HRESULT WINAPI DllCanUnloadNow(void)
 {
     return S_FALSE;
 }
 {
     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
 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
 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
 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
 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
 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.
    */
   /*
    * Reference count for that instance of the class.
    */
-  ULONG ref;
+  LONG ref;
 
   /*
    * This structure contains the description of the class.
 
   /*
    * This structure contains the description of the class.
@@ -2102,7 +2102,7 @@ typedef struct
 {
     /* IUnknown fields */
     const IClassFactoryVtbl    *lpVtbl;
 {
     /* IUnknown fields */
     const IClassFactoryVtbl    *lpVtbl;
-    DWORD                       ref;
+    LONG                        ref;
 } IClassFactoryImpl;
 
 static HRESULT WINAPI
 } IClassFactoryImpl;
 
 static HRESULT WINAPI
index 6d40403..171ee03 100644 (file)
@@ -76,7 +76,6 @@
 #include "wine/unicode.h"
 
 #include "wine/wingdi16.h"
 #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*/
 
 #ifdef HAVE_JPEGLIB_H
 /* This is a hack, so jpeglib.h does not redefine INT32 and the like*/
 
 WINE_DEFAULT_DEBUG_CHANNEL(ole);
 
 
 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
  */
 /*************************************************************************
  *  Declaration of implementation class
  */
@@ -109,7 +131,7 @@ typedef struct OLEPictureImpl {
     const IConnectionPointContainerVtbl *lpvtbl4;
 
   /* Object reference count */
     const IConnectionPointContainerVtbl *lpvtbl4;
 
   /* Object reference count */
-    DWORD ref;
+    LONG ref;
 
   /* We own the object and must destroy it ourselves */
     BOOL fOwn;
 
   /* 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;
     );
     /* */
     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;
     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) {
     
     /* 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;
       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.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);
     bmi->bmiHeader.biClrImportant      = 0;
 
     hdcref = GetDC(0);
@@ -2210,7 +2232,7 @@ typedef struct
 {
     /* IUnknown fields */
     const IClassFactoryVtbl    *lpVtbl;
 {
     /* IUnknown fields */
     const IClassFactoryVtbl    *lpVtbl;
-    DWORD                       ref;
+    LONG                        ref;
 } IClassFactoryImpl;
 
 static HRESULT WINAPI
 } IClassFactoryImpl;
 
 static HRESULT WINAPI
index 2ed6667..47c8bd7 100644 (file)
@@ -42,7 +42,7 @@ typedef struct {
 
 typedef struct {
     const IRecordInfoVtbl *lpVtbl;
 
 typedef struct {
     const IRecordInfoVtbl *lpVtbl;
-    ULONG ref;
+    LONG ref;
 
     GUID guid;
     UINT lib_index;
 
     GUID guid;
     UINT lib_index;
index 03c472e..daa9d55 100644 (file)
@@ -445,20 +445,20 @@ static GUID const CLSID_RecordInfo = {
 
 extern GUID const CLSID_PSDispatch;
 
 
 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} };
 
     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} };
 
     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} };
 
     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} };
 
     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} };
 
 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)
  */
 /***********************************************************************
  *             DllRegisterServer (OLEAUT32.320)
  */
-HRESULT WINAPI OLEAUT32_DllRegisterServer()
+HRESULT WINAPI DllRegisterServer(void)
 {
     HRESULT hr;
 
 {
     HRESULT hr;
 
@@ -918,7 +918,7 @@ HRESULT WINAPI OLEAUT32_DllRegisterServer()
 /***********************************************************************
  *             DllUnregisterServer (OLEAUT32.321)
  */
 /***********************************************************************
  *             DllUnregisterServer (OLEAUT32.321)
  */
-HRESULT WINAPI OLEAUT32_DllUnregisterServer()
+HRESULT WINAPI DllUnregisterServer(void)
 {
     HRESULT hr;
 
 {
     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];
     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",
     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);
     }
     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);
        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;
        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;
 typedef struct _TMProxyImpl {
     LPVOID                             *lpvtbl;
     const IRpcProxyBufferVtbl          *lpvtbl2;
-    ULONG                              ref;
+    LONG                               ref;
 
     TMAsmProxy                         *asmstubs;
     ITypeInfo*                         tinfo;
 
     TMAsmProxy                         *asmstubs;
     ITypeInfo*                         tinfo;
@@ -564,15 +565,18 @@ serialize_param(
         if (writeit) {
             /* ptr to ptr to magic widestring, basically */
             BSTR *bstr = (BSTR *) *arg;
         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 */
             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 {
             } 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) {
                    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 {
            } 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;
        }
            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;
        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 {
                    **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;
                    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 {
                    *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;
                    if (hres) {
                        ERR("Failed to read BSTR.\n");
                        return hres;
@@ -1275,6 +1288,15 @@ deserialize_param(
                    if (debugout) TRACE_(olerelay)("}");
                    break;
                }
                    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;
                default:
                    ERR("Unhandled typekind %d\n",tattr->typekind);
                    hres = E_FAIL;
@@ -1911,7 +1933,7 @@ PSFacBuf_CreateProxy(
 
 typedef struct _TMStubImpl {
     const IRpcStubBufferVtbl   *lpvtbl;
 
 typedef struct _TMStubImpl {
     const IRpcStubBufferVtbl   *lpvtbl;
-    ULONG                      ref;
+    LONG                       ref;
 
     LPUNKNOWN                  pUnk;
     ITypeInfo                  *tinfo;
 
     LPUNKNOWN                  pUnk;
     ITypeInfo                  *tinfo;
@@ -1952,6 +1974,7 @@ TMStubImpl_Release(LPRPCSTUBBUFFER iface)
     if (!refCount)
     {
         IRpcStubBuffer_Disconnect(iface);
     if (!refCount)
     {
         IRpcStubBuffer_Disconnect(iface);
+        ITypeInfo_Release(This->tinfo);
         CoTaskMemFree(This);
     }
     return refCount;
         CoTaskMemFree(This);
     }
     return refCount;
@@ -1976,9 +1999,11 @@ TMStubImpl_Disconnect(LPRPCSTUBBUFFER iface)
 
     TRACE("(%p)->()\n", This);
 
 
     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
 }
 
 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 } };
 
 /* 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
  *
 /****************************************************************************
  *              FromLExxx
  *
@@ -617,17 +619,8 @@ HRESULT WINAPI RegisterTypeLib(
                        MESSAGE("\n");
                    }
 
                        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,
                        /* 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;
 {
     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*
     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;
 {
     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; */
     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);
 }
   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++) {
   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);
 }
 
   dump_ELEMDESC(&funcdesc->elemdescFunc);
 }
 
-void dump_IDLDESC(IDLDESC *idl) {
-  MESSAGE("\t\twIdlflags: %d\n",idl->wIDLFlags);
-}
-
 static const char * typekind_desc[] =
 {
        "TKIND_ENUM",
 static const char * typekind_desc[] =
 {
        "TKIND_ENUM",
@@ -1133,27 +1122,6 @@ static const char * typekind_desc[] =
        "TKIND_MAX"
 };
 
        "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;
 static void dump_TLBFuncDescOne(TLBFuncDesc * pfd)
 {
   int i;
@@ -1305,7 +1273,7 @@ static void dump_TypeInfo(ITypeInfoImpl * pty)
     dump_TLBImplType(pty->impltypelist);
 }
 
     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));
 {
     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 */
  *  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);
 {
     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));
 }
 
     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;
 {
     char * name;
     MSFT_NameIntro niName;
@@ -1489,7 +1457,7 @@ BSTR MSFT_ReadName( TLBContext *pcx, int offset)
     return bstrName;
 }
 
     return bstrName;
 }
 
-BSTR MSFT_ReadString( TLBContext *pcx, int offset)
+static BSTR MSFT_ReadString( TLBContext *pcx, int offset)
 {
     char * string;
     INT16 length;
 {
     char * string;
     INT16 length;
@@ -1997,8 +1965,11 @@ static void MSFT_DoRefType(TLBContext *pcx, ITypeInfoImpl *pTI,
         if(pImpLib){
             (*ppRefType)->reference=offset;
             (*ppRefType)->pImpTLInfo = pImpLib;
         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;
         }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
  */
 /*
  * process a typeinfo record
  */
-ITypeInfoImpl * MSFT_DoTypeInfo(
+static ITypeInfoImpl * MSFT_DoTypeInfo(
     TLBContext *pcx,
     int count,
     ITypeLibImpl * pLibInfo)
     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;
              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;
           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;
 }
 
     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.@)
  */
 /***********************************************************************
  *             DispCallFunc (OLEAUT32.@)
  */
@@ -4772,6 +4864,11 @@ static HRESULT WINAPI ITypeInfo_fnInvoke(
 
         hres = ITypeInfo2_GetFuncDesc(iface, func_index, &func_desc);
         if(FAILED(hres)) return hres;
 
         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:
         
        switch (func_desc->funckind) {
        case FUNC_PUREVIRTUAL:
@@ -4873,76 +4970,36 @@ static HRESULT WINAPI ITypeInfo_fnInvoke(
                    args
            );
 
                    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;
                             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);
 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 */
                                 /* 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 {
 
 /* 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) */
                             /* 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 {
 
 /* function description data */
 typedef struct {
index 01abb2d..aedb499 100644 (file)
@@ -80,7 +80,7 @@ QueryPathOfRegTypeLib16(
 {
        char    xguid[80];
        char    typelibkey[100],pathname[260];
 {
        char    xguid[80];
        char    typelibkey[100],pathname[260];
-       DWORD   plen;
+       LONG    plen;
 
                TRACE("\n");
 
 
                TRACE("\n");
 
index 14d9112..ffc5b88 100644 (file)
@@ -148,7 +148,7 @@ typedef struct tagICreateTypeLib2Impl
     const ICreateTypeLib2Vtbl *lpVtbl;
     const ITypeLib2Vtbl       *lpVtblTypeLib2;
 
     const ICreateTypeLib2Vtbl *lpVtbl;
     const ITypeLib2Vtbl       *lpVtblTypeLib2;
 
-    ULONG ref;
+    LONG ref;
 
     WCHAR *filename;
 
 
     WCHAR *filename;
 
@@ -174,7 +174,7 @@ typedef struct tagICreateTypeInfo2Impl
     const ICreateTypeInfo2Vtbl *lpVtbl;
     const ITypeInfo2Vtbl       *lpVtblTypeInfo2;
 
     const ICreateTypeInfo2Vtbl *lpVtbl;
     const ITypeInfo2Vtbl       *lpVtblTypeInfo2;
 
-    ULONG ref;
+    LONG ref;
 
     ICreateTypeLib2Impl *typelib;
     MSFT_TypeInfoBase *typeinfo;
 
     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;
 
        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);
        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);
 {
   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),
   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)
   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);
 
   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_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));
     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_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));
     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_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));
     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;
     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));
     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_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));
     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_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));
     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_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));
     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_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));
     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]
 
 /**********************************************************************
  *              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)
 {
  */
 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]
  *
 /**********************************************************************
  *              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)
 {
  */
 HRESULT WINAPI VarAnd(LPVARIANT left, LPVARIANT right, LPVARIANT result)
 {
@@ -3073,6 +3082,16 @@ end:
 /**********************************************************************
  *              VarDiv [OLEAUT32.143]
  *
 /**********************************************************************
  *              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)
 {
  */
 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]
  *
 /**********************************************************************
  *              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)
 {
  */
 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]
  *
 /**********************************************************************
  *              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)
 {
  */
 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 );
     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)
   {
   TRACE("created string %s\n", debugstr_w(buff));
   if (dwFlags & LOCALE_USE_NLS)
   {