From a48a2273ec0fa12a52f1d8cb4ac5ad7dd128cfc4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9=20van=20Geldorp?= Date: Fri, 12 Aug 2005 17:30:09 +0000 Subject: [PATCH] Sync to Wine-20050725: Huw Davies for Mandriva - Cope with the index in a import table entry being a typeinfo index rather than a guid offset. Robert Shearman - 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 - 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 - Get rid of cursoricon.h. Mike McCormack - gcc 4.0 -Wpointer-sign fixes (Reg* functions). - Interlocked LONG* gcc warning fixes. Stefan Huehner - Fix some more -Wmissing-declarations warnings. Robert Shearman 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 --- reactos/include/wine/unicode.h | 1 + reactos/lib/oleaut32/connpt.c | 4 +- reactos/lib/oleaut32/dispatch.c | 2 +- reactos/lib/oleaut32/oleaut.c | 49 ++++- reactos/lib/oleaut32/oleaut32.spec | 8 +- reactos/lib/oleaut32/olefont.c | 4 +- reactos/lib/oleaut32/olepicture.c | 36 +++- reactos/lib/oleaut32/recinfo.c | 2 +- reactos/lib/oleaut32/regsvr.c | 16 +- reactos/lib/oleaut32/tmarshal.c | 81 ++++++--- reactos/lib/oleaut32/typelib.c | 281 +++++++++++++++++------------ reactos/lib/oleaut32/typelib.h | 8 +- reactos/lib/oleaut32/typelib16.c | 2 +- reactos/lib/oleaut32/typelib2.c | 6 +- reactos/lib/oleaut32/variant.c | 79 ++++++-- reactos/lib/oleaut32/vartype.c | 13 ++ 16 files changed, 395 insertions(+), 197 deletions(-) diff --git a/reactos/include/wine/unicode.h b/reactos/include/wine/unicode.h index c0e9f947240..66453e78382 100644 --- a/reactos/include/wine/unicode.h +++ b/reactos/include/wine/unicode.h @@ -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)) diff --git a/reactos/lib/oleaut32/connpt.c b/reactos/lib/oleaut32/connpt.c index f13bd6784ff..da0ffcc40e9 100644 --- a/reactos/lib/oleaut32/connpt.c +++ b/reactos/lib/oleaut32/connpt.c @@ -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; diff --git a/reactos/lib/oleaut32/dispatch.c b/reactos/lib/oleaut32/dispatch.c index fd9d7b2c4d9..fbee4d8f09b 100644 --- a/reactos/lib/oleaut32/dispatch.c +++ b/reactos/lib/oleaut32/dispatch.c @@ -217,7 +217,7 @@ typedef struct const IDispatchVtbl *lpVtbl; void * pvThis; ITypeInfo * pTypeInfo; - ULONG ref; + LONG ref; } StdDispatch; /****************************************************************************** diff --git a/reactos/lib/oleaut32/oleaut.c b/reactos/lib/oleaut32/oleaut.c index 1527fed33b7..b9125b48019 100644 --- a/reactos/lib/oleaut32/oleaut.c +++ b/reactos/lib/oleaut32/oleaut.c @@ -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; } diff --git a/reactos/lib/oleaut32/oleaut32.spec b/reactos/lib/oleaut32/oleaut32.spec index c49de8136bc..2be07f65d7b 100644 --- a/reactos/lib/oleaut32/oleaut32.spec +++ b/reactos/lib/oleaut32/oleaut32.spec @@ -1,4 +1,4 @@ -1 stdcall -private DllGetClassObject(ptr ptr ptr) OLEAUT32_DllGetClassObject +1 stdcall -private DllGetClassObject(ptr ptr ptr) 2 stdcall SysAllocString(wstr) 3 stdcall SysReAllocString(ptr wstr) 4 stdcall SysAllocStringLen(wstr long) @@ -312,8 +312,8 @@ 317 stdcall VarR8Round(double long ptr) 318 stdcall VarCat(ptr ptr ptr) 319 stdcall VarDateFromUdateEx(ptr long long ptr) -320 stdcall -private DllRegisterServer() OLEAUT32_DllRegisterServer -321 stdcall -private DllUnregisterServer() OLEAUT32_DllUnregisterServer +320 stdcall -private DllRegisterServer() +321 stdcall -private DllUnregisterServer() 322 stdcall GetRecordInfoFromGuids(ptr long long long ptr ptr) 323 stdcall GetRecordInfoFromTypeInfo(ptr ptr) 325 stub SetVarConversionLocaleSetting @@ -382,7 +382,7 @@ 399 stub UserMSG_free_local 401 stdcall OleLoadPictureEx(ptr long long long long long long ptr) 402 stub OleLoadPictureFileEx -410 stdcall -private DllCanUnloadNow() OLEAUT32_DllCanUnloadNow +410 stdcall -private DllCanUnloadNow() 411 stdcall SafeArrayCreateVector(long long long) 412 stdcall SafeArrayCopyData(ptr ptr) 413 stdcall VectorFromBstr(ptr ptr) diff --git a/reactos/lib/oleaut32/olefont.c b/reactos/lib/oleaut32/olefont.c index 2e6395ac8eb..0fce581c084 100644 --- a/reactos/lib/oleaut32/olefont.c +++ b/reactos/lib/oleaut32/olefont.c @@ -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 diff --git a/reactos/lib/oleaut32/olepicture.c b/reactos/lib/oleaut32/olepicture.c index 6d404037013..171ee0313cd 100644 --- a/reactos/lib/oleaut32/olepicture.c +++ b/reactos/lib/oleaut32/olepicture.c @@ -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*/ @@ -93,6 +92,29 @@ 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<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<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 diff --git a/reactos/lib/oleaut32/recinfo.c b/reactos/lib/oleaut32/recinfo.c index 2ed6667f281..47c8bd734dc 100644 --- a/reactos/lib/oleaut32/recinfo.c +++ b/reactos/lib/oleaut32/recinfo.c @@ -42,7 +42,7 @@ typedef struct { typedef struct { const IRecordInfoVtbl *lpVtbl; - ULONG ref; + LONG ref; GUID guid; UINT lib_index; diff --git a/reactos/lib/oleaut32/regsvr.c b/reactos/lib/oleaut32/regsvr.c index 03c472e73a2..daa9d55ff85 100644 --- a/reactos/lib/oleaut32/regsvr.c +++ b/reactos/lib/oleaut32/regsvr.c @@ -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; diff --git a/reactos/lib/oleaut32/tmarshal.c b/reactos/lib/oleaut32/tmarshal.c index 7960ee66060..720dc740ef8 100644 --- a/reactos/lib/oleaut32/tmarshal.c +++ b/reactos/lib/oleaut32/tmarshal.c @@ -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<"); } 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)(""); } 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)(""); } 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 diff --git a/reactos/lib/oleaut32/typelib.c b/reactos/lib/oleaut32/typelib.c index 869f90bd5c0..e49fa4af590 100644 --- a/reactos/lib/oleaut32/typelib.c +++ b/reactos/lib/oleaut32/typelib.c @@ -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;icParams;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); diff --git a/reactos/lib/oleaut32/typelib.h b/reactos/lib/oleaut32/typelib.h index 6f7b8cd4330..5e9c90f33b2 100644 --- a/reactos/lib/oleaut32/typelib.h +++ b/reactos/lib/oleaut32/typelib.h @@ -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 { diff --git a/reactos/lib/oleaut32/typelib16.c b/reactos/lib/oleaut32/typelib16.c index 01abb2d9dd8..aedb499f9dd 100644 --- a/reactos/lib/oleaut32/typelib16.c +++ b/reactos/lib/oleaut32/typelib16.c @@ -80,7 +80,7 @@ QueryPathOfRegTypeLib16( { char xguid[80]; char typelibkey[100],pathname[260]; - DWORD plen; + LONG plen; TRACE("\n"); diff --git a/reactos/lib/oleaut32/typelib2.c b/reactos/lib/oleaut32/typelib2.c index 14d91126d39..ffc5b88d797 100644 --- a/reactos/lib/oleaut32/typelib2.c +++ b/reactos/lib/oleaut32/typelib2.c @@ -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); diff --git a/reactos/lib/oleaut32/variant.c b/reactos/lib/oleaut32/variant.c index 4a9985a6c73..0a80e76ecda 100644 --- a/reactos/lib/oleaut32/variant.c +++ b/reactos/lib/oleaut32/variant.c @@ -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) { diff --git a/reactos/lib/oleaut32/vartype.c b/reactos/lib/oleaut32/vartype.c index a82b6922992..0e1b7e836f8 100644 --- a/reactos/lib/oleaut32/vartype.c +++ b/reactos/lib/oleaut32/vartype.c @@ -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) {