Sync to Wine-20050725:

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
This commit is contained in:
Gé van Geldorp 2005-08-12 17:30:09 +00:00
parent 7835b350bb
commit a48a2273ec
16 changed files with 395 additions and 197 deletions

View file

@ -20,6 +20,7 @@
#define strcmpiW(s1,s2) _wcsicmp((const wchar_t *)(s1),(const wchar_t *)(s2)) #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 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 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 tolowerW(n) towlower((n))
#define toupperW(n) towupper((n)) #define toupperW(n) towupper((n))
#define islowerW(n) iswlower((n)) #define islowerW(n) iswlower((n))

View file

@ -54,7 +54,7 @@ typedef struct ConnectionPointImpl {
IUnknown *Obj; IUnknown *Obj;
/* Reference count */ /* Reference count */
DWORD ref; LONG ref;
/* IID of sink interface */ /* IID of sink interface */
IID iid; 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 of ConnectionPoint, used for ref counting */
IUnknown *pUnk; IUnknown *pUnk;

View file

@ -217,7 +217,7 @@ typedef struct
const IDispatchVtbl *lpVtbl; const IDispatchVtbl *lpVtbl;
void * pvThis; void * pvThis;
ITypeInfo * pTypeInfo; ITypeInfo * pTypeInfo;
ULONG ref; LONG ref;
} StdDispatch; } StdDispatch;
/****************************************************************************** /******************************************************************************

View file

@ -42,8 +42,11 @@ WINE_DEFAULT_DEBUG_CHANNEL(ole);
/* The OLE Automation ProxyStub Interface Class (aka Typelib Marshaler) */ /* The OLE Automation ProxyStub Interface Class (aka Typelib Marshaler) */
extern const GUID CLSID_PSOAInterface; 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( HRESULT WINAPI RegisterActiveObject(
LPUNKNOWN punk,REFCLSID rcid,DWORD dwFlags,LPDWORD pdwRegister 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; *ppv = NULL;
if (IsEqualGUID(rclsid,&CLSID_StdFont)) { 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)) { if (IsEqualCLSID(rclsid, &CLSID_PSDispatch) ||
return OLEAUTPS_DllGetClassObject(rclsid,iid,ppv); 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 (IsEqualGUID(rclsid,&CLSID_PSOAInterface)) {
if (S_OK==TypeLibFac_DllGetClassObject(rclsid,iid,ppv)) if (S_OK==TypeLibFac_DllGetClassObject(rclsid,iid,ppv))
@ -707,7 +746,7 @@ HRESULT WINAPI OLEAUT32_DllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *p
* RETURNS * RETURNS
* Always returns S_FALSE. This dll cannot be unloaded. * Always returns S_FALSE. This dll cannot be unloaded.
*/ */
HRESULT WINAPI OLEAUT32_DllCanUnloadNow(void) HRESULT WINAPI DllCanUnloadNow(void)
{ {
return S_FALSE; return S_FALSE;
} }

View file

@ -1,4 +1,4 @@
1 stdcall -private DllGetClassObject(ptr ptr ptr) OLEAUT32_DllGetClassObject 1 stdcall -private DllGetClassObject(ptr ptr ptr)
2 stdcall SysAllocString(wstr) 2 stdcall SysAllocString(wstr)
3 stdcall SysReAllocString(ptr wstr) 3 stdcall SysReAllocString(ptr wstr)
4 stdcall SysAllocStringLen(wstr long) 4 stdcall SysAllocStringLen(wstr long)
@ -312,8 +312,8 @@
317 stdcall VarR8Round(double long ptr) 317 stdcall VarR8Round(double long ptr)
318 stdcall VarCat(ptr ptr ptr) 318 stdcall VarCat(ptr ptr ptr)
319 stdcall VarDateFromUdateEx(ptr long long ptr) 319 stdcall VarDateFromUdateEx(ptr long long ptr)
320 stdcall -private DllRegisterServer() OLEAUT32_DllRegisterServer 320 stdcall -private DllRegisterServer()
321 stdcall -private DllUnregisterServer() OLEAUT32_DllUnregisterServer 321 stdcall -private DllUnregisterServer()
322 stdcall GetRecordInfoFromGuids(ptr long long long ptr ptr) 322 stdcall GetRecordInfoFromGuids(ptr long long long ptr ptr)
323 stdcall GetRecordInfoFromTypeInfo(ptr ptr) 323 stdcall GetRecordInfoFromTypeInfo(ptr ptr)
325 stub SetVarConversionLocaleSetting 325 stub SetVarConversionLocaleSetting
@ -382,7 +382,7 @@
399 stub UserMSG_free_local 399 stub UserMSG_free_local
401 stdcall OleLoadPictureEx(ptr long long long long long long ptr) 401 stdcall OleLoadPictureEx(ptr long long long long long long ptr)
402 stub OleLoadPictureFileEx 402 stub OleLoadPictureFileEx
410 stdcall -private DllCanUnloadNow() OLEAUT32_DllCanUnloadNow 410 stdcall -private DllCanUnloadNow()
411 stdcall SafeArrayCreateVector(long long long) 411 stdcall SafeArrayCreateVector(long long long)
412 stdcall SafeArrayCopyData(ptr ptr) 412 stdcall SafeArrayCopyData(ptr ptr)
413 stdcall VectorFromBstr(ptr ptr) 413 stdcall VectorFromBstr(ptr ptr)

View 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 */ /* IUnknown fields */
const IClassFactoryVtbl *lpVtbl; const IClassFactoryVtbl *lpVtbl;
DWORD ref; LONG ref;
} IClassFactoryImpl; } IClassFactoryImpl;
static HRESULT WINAPI static HRESULT WINAPI

View file

@ -76,7 +76,6 @@
#include "wine/unicode.h" #include "wine/unicode.h"
#include "wine/wingdi16.h" #include "wine/wingdi16.h"
#include "cursoricon.h"
#ifdef HAVE_JPEGLIB_H #ifdef HAVE_JPEGLIB_H
/* This is a hack, so jpeglib.h does not redefine INT32 and the like*/ /* This is a hack, so jpeglib.h does not redefine INT32 and the like*/
@ -93,6 +92,29 @@
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; const IConnectionPointContainerVtbl *lpvtbl4;
/* Object reference count */ /* Object reference count */
DWORD ref; LONG ref;
/* We own the object and must destroy it ourselves */ /* We own the object and must destroy it ourselves */
BOOL fOwn; 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; si = gif->SavedImages+0;
gid = &(si->ImageDesc); gid = &(si->ImageDesc);
cm = gid->ColorMap; cm = gid->ColorMap;
if (!cm) cm = gif->SColorMap; 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 */ /* look for the transparent color extension */
for (i = 0; i < si->ExtensionBlockCount; ++i) { 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].rgbRed = cm->Colors[i].Red;
bmi->bmiColors[i].rgbGreen = cm->Colors[i].Green; bmi->bmiColors[i].rgbGreen = cm->Colors[i].Green;
bmi->bmiColors[i].rgbBlue = cm->Colors[i].Blue; 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.biSizeImage = padding*gif->SHeight;
bmi->bmiHeader.biXPelsPerMeter = 0; bmi->bmiHeader.biXPelsPerMeter = 0;
bmi->bmiHeader.biYPelsPerMeter = 0; bmi->bmiHeader.biYPelsPerMeter = 0;
bmi->bmiHeader.biClrUsed = 1 << gif->SColorResolution; bmi->bmiHeader.biClrUsed = cm->ColorCount;
bmi->bmiHeader.biClrImportant = 0; bmi->bmiHeader.biClrImportant = 0;
hdcref = GetDC(0); hdcref = GetDC(0);
@ -2210,7 +2232,7 @@ typedef struct
{ {
/* IUnknown fields */ /* IUnknown fields */
const IClassFactoryVtbl *lpVtbl; const IClassFactoryVtbl *lpVtbl;
DWORD ref; LONG ref;
} IClassFactoryImpl; } IClassFactoryImpl;
static HRESULT WINAPI static HRESULT WINAPI

View file

@ -42,7 +42,7 @@ typedef struct {
typedef struct { typedef struct {
const IRecordInfoVtbl *lpVtbl; const IRecordInfoVtbl *lpVtbl;
ULONG ref; LONG ref;
GUID guid; GUID guid;
UINT lib_index; UINT lib_index;

View 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; GUID const CLSID_PSTypeComp = {
static 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 = { static GUID const CLSID_OldFont = {
0x46763EE0, 0xCAB2, 0x11CE, {0x8C,0x20,0x00,0xAA,0x00,0x51,0xE5,0xD4} }; 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;

View file

@ -262,7 +262,8 @@ _get_typeinfo_for_iid(REFIID riid, ITypeInfo**ti) {
char tlguid[200],typelibkey[300],interfacekey[300],ver[100]; char tlguid[200],typelibkey[300],interfacekey[300],ver[100];
char tlfn[260]; char tlfn[260];
OLECHAR tlfnW[260]; OLECHAR tlfnW[260];
DWORD tlguidlen, verlen, type, tlfnlen; DWORD tlguidlen, verlen, type;
LONG tlfnlen;
ITypeLib *tl; ITypeLib *tl;
sprintf( interfacekey, "Interface\\{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}\\Typelib", 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); type = (1<<REG_SZ);
tlguidlen = sizeof(tlguid); 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"); ERR("Getting typelib guid failed.\n");
RegCloseKey(ikey); RegCloseKey(ikey);
return E_FAIL; return E_FAIL;
} }
type = (1<<REG_SZ); type = (1<<REG_SZ);
verlen = sizeof(ver); 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"); ERR("Could not get version value?\n");
RegCloseKey(ikey); RegCloseKey(ikey);
return E_FAIL; return E_FAIL;
@ -357,7 +358,7 @@ typedef struct _TMAsmProxy {
typedef struct _TMProxyImpl { typedef struct _TMProxyImpl {
LPVOID *lpvtbl; LPVOID *lpvtbl;
const IRpcProxyBufferVtbl *lpvtbl2; const IRpcProxyBufferVtbl *lpvtbl2;
ULONG ref; LONG ref;
TMAsmProxy *asmstubs; TMAsmProxy *asmstubs;
ITypeInfo* tinfo; ITypeInfo* tinfo;
@ -564,15 +565,18 @@ serialize_param(
if (writeit) { if (writeit) {
/* ptr to ptr to magic widestring, basically */ /* ptr to ptr to magic widestring, basically */
BSTR *bstr = (BSTR *) *arg; BSTR *bstr = (BSTR *) *arg;
DWORD len;
if (!*bstr) { if (!*bstr) {
/* -1 means "null string" which is equivalent to empty string */ /* -1 means "null string" which is equivalent to empty string */
DWORD fakelen = -1; len = -1;
xbuf_add(buf, (LPBYTE)&fakelen,4); hres = xbuf_add(buf, (LPBYTE)&len,sizeof(DWORD));
if (hres) return hres;
} else { } else {
/* BSTRs store the length behind the first character */ len = *((DWORD*)*bstr-1)/sizeof(WCHAR);
DWORD *len = ((DWORD *)(*bstr))-1; hres = xbuf_add(buf,(LPBYTE)&len,sizeof(DWORD));
hres = xbuf_add(buf, (LPBYTE) len, *len + 4); if (hres) return hres;
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>"); TRACE_(olerelay)("<bstr NULL>");
} }
if (writeit) { if (writeit) {
if (!*arg) { BSTR bstr = (BSTR)*arg;
DWORD fakelen = -1; DWORD len;
hres = xbuf_add(buf,(LPBYTE)&fakelen,4); if (!bstr) {
if (hres) len = -1;
return hres; hres = xbuf_add(buf,(LPBYTE)&len,sizeof(DWORD));
if (hres) return hres;
} else { } else {
DWORD *bstr = ((DWORD*)(*arg))-1; len = *((DWORD*)bstr-1)/sizeof(WCHAR);
hres = xbuf_add(buf,(LPBYTE)&len,sizeof(DWORD));
hres = xbuf_add(buf,(LPBYTE)bstr,bstr[0]+4); if (hres) return hres;
if (hres) hres = xbuf_add(buf,(LPBYTE)bstr,len * sizeof(WCHAR));
return hres; if (hres) return hres;
} }
} }
@ -704,6 +709,14 @@ serialize_param(
if (debugout) TRACE_(olerelay)("}"); if (debugout) TRACE_(olerelay)("}");
break; 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: default:
FIXME("Unhandled typekind %d\n",tattr->typekind); FIXME("Unhandled typekind %d\n",tattr->typekind);
hres = E_FAIL; hres = E_FAIL;
@ -1130,8 +1143,8 @@ deserialize_param(
**bstr = NULL; **bstr = NULL;
if (debugout) TRACE_(olerelay)("<bstr NULL>"); if (debugout) TRACE_(olerelay)("<bstr NULL>");
} else { } else {
str = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,len+sizeof(WCHAR)); str = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,(len+1)*sizeof(WCHAR));
hres = xbuf_get(buf,(LPBYTE)str,len); hres = xbuf_get(buf,(LPBYTE)str,len*sizeof(WCHAR));
if (hres) { if (hres) {
ERR("Failed to read BSTR.\n"); ERR("Failed to read BSTR.\n");
return hres; return hres;
@ -1160,8 +1173,8 @@ deserialize_param(
*arg = 0; *arg = 0;
if (debugout) TRACE_(olerelay)("<bstr NULL>"); if (debugout) TRACE_(olerelay)("<bstr NULL>");
} else { } else {
str = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,len+sizeof(WCHAR)); str = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,(len+1)*sizeof(WCHAR));
hres = xbuf_get(buf,(LPBYTE)str,len); hres = xbuf_get(buf,(LPBYTE)str,len*sizeof(WCHAR));
if (hres) { if (hres) {
ERR("Failed to read BSTR.\n"); ERR("Failed to read BSTR.\n");
return hres; return hres;
@ -1275,6 +1288,15 @@ deserialize_param(
if (debugout) TRACE_(olerelay)("}"); if (debugout) TRACE_(olerelay)("}");
break; 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: default:
ERR("Unhandled typekind %d\n",tattr->typekind); ERR("Unhandled typekind %d\n",tattr->typekind);
hres = E_FAIL; hres = E_FAIL;
@ -1911,7 +1933,7 @@ PSFacBuf_CreateProxy(
typedef struct _TMStubImpl { typedef struct _TMStubImpl {
const IRpcStubBufferVtbl *lpvtbl; const IRpcStubBufferVtbl *lpvtbl;
ULONG ref; LONG ref;
LPUNKNOWN pUnk; LPUNKNOWN pUnk;
ITypeInfo *tinfo; ITypeInfo *tinfo;
@ -1952,6 +1974,7 @@ TMStubImpl_Release(LPRPCSTUBBUFFER iface)
if (!refCount) if (!refCount)
{ {
IRpcStubBuffer_Disconnect(iface); IRpcStubBuffer_Disconnect(iface);
ITypeInfo_Release(This->tinfo);
CoTaskMemFree(This); CoTaskMemFree(This);
} }
return refCount; return refCount;
@ -1976,9 +1999,11 @@ TMStubImpl_Disconnect(LPRPCSTUBBUFFER iface)
TRACE("(%p)->()\n", This); TRACE("(%p)->()\n", This);
IUnknown_Release(This->pUnk); if (This->pUnk)
This->pUnk = NULL; {
return; IUnknown_Release(This->pUnk);
This->pUnk = NULL;
}
} }
static HRESULT WINAPI static HRESULT WINAPI

View file

@ -84,6 +84,8 @@ WINE_DECLARE_DEBUG_CHANNEL(typelib);
/* The OLE Automation ProxyStub Interface Class (aka Typelib Marshaler) */ /* The OLE Automation ProxyStub Interface Class (aka Typelib Marshaler) */
const GUID CLSID_PSOAInterface = { 0x00020424, 0, 0, { 0xC0, 0, 0, 0, 0, 0, 0, 0x46 } }; 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");
} }
/* if (tattr->wTypeFlags & (TYPEFLAG_FOLEAUTOMATION|TYPEFLAG_FDUAL))
* 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)) {
FIXME("Registering non-oleautomation interface!\n");
}
/* register interface<->typelib coupling */ /* register interface<->typelib coupling */
get_interface_key( &tattr->guid, keyName ); get_interface_key( &tattr->guid, keyName );
if (RegCreateKeyExW(HKEY_CLASSES_ROOT, keyName, 0, NULL, 0, if (RegCreateKeyExW(HKEY_CLASSES_ROOT, keyName, 0, NULL, 0,
@ -863,7 +856,7 @@ typedef struct tagITypeLibImpl
{ {
const ITypeLib2Vtbl *lpVtbl; const ITypeLib2Vtbl *lpVtbl;
const ITypeCompVtbl *lpVtblTypeComp; const ITypeCompVtbl *lpVtblTypeComp;
ULONG ref; LONG ref;
TLIBATTR LibAttr; /* guid,lcid,syskind,version,flags */ TLIBATTR LibAttr; /* guid,lcid,syskind,version,flags */
/* strings can be stored in tlb as multibyte strings BUT they are *always* /* strings can be stored in tlb as multibyte strings BUT they are *always*
@ -975,7 +968,7 @@ typedef struct tagITypeInfoImpl
{ {
const ITypeInfo2Vtbl *lpVtbl; const ITypeInfo2Vtbl *lpVtbl;
const ITypeCompVtbl *lpVtblTypeComp; const ITypeCompVtbl *lpVtblTypeComp;
ULONG ref; LONG ref;
TYPEATTR TypeAttr ; /* _lots_ of type information. */ TYPEATTR TypeAttr ; /* _lots_ of type information. */
ITypeLibImpl * pTypeLib; /* back pointer to typelib */ ITypeLibImpl * pTypeLib; /* back pointer to typelib */
int index; /* index in this 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]; char buf[200];
dump_TypeDesc(&edesc->tdesc,buf); dump_TypeDesc(&edesc->tdesc,buf);
MESSAGE("\t\ttdesc.vartype %d (%s)\n",edesc->tdesc.vt,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.flags %x\n",edesc->u.paramdesc.wParamFlags);
MESSAGE("\t\tu.parmadesc.lpex %p\n",edesc->u.paramdesc.pparamdescex); MESSAGE("\t\tu.parmadesc.lpex %p\n",edesc->u.paramdesc.pparamdescex);
} }
void dump_FUNCDESC(FUNCDESC *funcdesc) { static void dump_FUNCDESC(FUNCDESC *funcdesc) {
int i; int i;
MESSAGE("memid is %08lx\n",funcdesc->memid); MESSAGE("memid is %08lx\n",funcdesc->memid);
for (i=0;i<funcdesc->cParams;i++) { 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[] = static const char * typekind_desc[] =
{ {
"TKIND_ENUM", "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) static void dump_TLBFuncDescOne(TLBFuncDesc * pfd)
{ {
int i; 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("memid %ld\n",v->memid);
MESSAGE("lpstrSchema %s\n",debugstr_w(v->lpstrSchema)); 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) * Functions for reading MSFT typelibs (those created by CreateTypeLib2)
*/ */
/* read function */ /* 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", TRACE_(typelib)("pos=0x%08x len=0x%08lx 0x%08x 0x%08x 0x%08lx\n",
pcx->pos, count, pcx->oStart, pcx->length, where); 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; char * name;
MSFT_NameIntro niName; 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; char * string;
INT16 length; INT16 length;
@ -1997,8 +1965,11 @@ static void MSFT_DoRefType(TLBContext *pcx, ITypeInfoImpl *pTI,
if(pImpLib){ if(pImpLib){
(*ppRefType)->reference=offset; (*ppRefType)->reference=offset;
(*ppRefType)->pImpTLInfo = pImpLib; (*ppRefType)->pImpTLInfo = pImpLib;
MSFT_ReadGuid(&(*ppRefType)->guid, impinfo.oGuid, pcx); if(impinfo.flags & MSFT_IMPINFO_OFFSET_IS_GUID) {
(*ppRefType)->index = TLB_REF_USE_GUID; MSFT_ReadGuid(&(*ppRefType)->guid, impinfo.oGuid, pcx);
(*ppRefType)->index = TLB_REF_USE_GUID;
} else
(*ppRefType)->index = impinfo.oGuid;
}else{ }else{
ERR("Cannot find a reference\n"); ERR("Cannot find a reference\n");
(*ppRefType)->reference=-1; (*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, TLBContext *pcx,
int count, int count,
ITypeLibImpl * pLibInfo) ITypeLibImpl * pLibInfo)
@ -4617,6 +4588,10 @@ _copy_arg( ITypeInfo2 *tinfo, TYPEDESC *tdesc,
memcpy(argpos, &V_I4(arg), 4); memcpy(argpos, &V_I4(arg), 4);
hres = S_OK; hres = S_OK;
break; break;
case VT_BYREF|VT_I4:
memcpy(argpos, V_I4REF(arg), 4);
hres = S_OK;
break;
default: default:
FIXME("vt 0x%x -> TKIND_ENUM unhandled.\n",V_VT(arg)); FIXME("vt 0x%x -> TKIND_ENUM unhandled.\n",V_VT(arg));
hres = E_FAIL; 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); hres = ITypeInfo2_GetFuncDesc(iface, func_index, &func_desc);
if(FAILED(hres)) return hres; if(FAILED(hres)) return hres;
if (TRACE_ON(ole))
{
TRACE("invoking:\n");
dump_FUNCDESC(func_desc);
}
switch (func_desc->funckind) { switch (func_desc->funckind) {
case FUNC_PUREVIRTUAL: case FUNC_PUREVIRTUAL:
@ -4873,76 +4970,36 @@ static HRESULT WINAPI ITypeInfo_fnInvoke(
args args
); );
if (pVarResult && (dwFlags & (DISPATCH_PROPERTYGET))) { if (pVarResult) {
args2pos = 0; for (i = 0; i < func_desc->cParams; i++) {
for (i = 0; i < func_desc->cParams - pDispParams->cArgs; i++) { USHORT wParamFlags = func_desc->lprgelemdescParam[i].u.paramdesc.wParamFlags;
ELEMDESC *elemdesc = &(func_desc->lprgelemdescParam[i+pDispParams->cArgs]); if (wParamFlags & PARAMFLAG_FRETVAL) {
TYPEDESC *tdesc = &(elemdesc->tdesc); ELEMDESC *elemdesc = &func_desc->lprgelemdescParam[i];
int arglen = _argsize(tdesc->vt); TYPEDESC *tdesc = &elemdesc->tdesc;
TYPEDESC i4_tdesc; VARIANTARG varresult;
i4_tdesc.vt = VT_I4; V_VT(&varresult) = 0;
hres = typedescvt_to_variantvt((ITypeInfo *)iface, tdesc, &V_VT(&varresult));
/* If we are a pointer to a variant, we are done already */ if (hres)
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;
break; break;
case TKIND_ALIAS: /* FIXME: this is really messy - we should keep the
TRACE("TKIND_ALIAS to vt 0x%x\n",tattr->tdescAlias.vt); * args in VARIANTARGs rather than a DWORD array */
tdesc = &(tattr->tdescAlias); memcpy(&V_UI4(&varresult), &args[i+1], sizeof(DWORD));
break; if (TRACE_ON(ole))
{
case TKIND_INTERFACE: TRACE("varresult: ");
FIXME("TKIND_INTERFACE unhandled.\n"); dump_Variant(&varresult);
break; }
case TKIND_DISPATCH: hres = VariantCopyInd(pVarResult, &varresult);
FIXME("TKIND_DISPATCH unhandled.\n"); break;
break;
case TKIND_RECORD:
FIXME("TKIND_RECORD unhandled.\n");
break;
default:
FIXME("TKIND %d unhandled.\n",tattr->typekind);
break;
}
ITypeInfo_Release(tinfo2);
} }
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: func_fail:
HeapFree(GetProcessHeap(), 0, rgvarg); HeapFree(GetProcessHeap(), 0, rgvarg);
HeapFree(GetProcessHeap(),0,args2); HeapFree(GetProcessHeap(),0,args2);

View file

@ -157,17 +157,19 @@ typedef struct tagMSFT_TypeInfoBase {
/* else it is zero? */ /* else it is zero? */
INT res18; /* always? 0 */ INT res18; /* always? 0 */
/*060*/ INT res19; /* always? -1 */ /*060*/ INT res19; /* always? -1 */
} MSFT_TypeInfoBase; } MSFT_TypeInfoBase;
/* layout of an entry with information on imported types */ /* layout of an entry with information on imported types */
typedef struct tagMSFT_ImpInfo { 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 */ /* bit 16: if set oGuid is an offset to Guid */
/* if clear oGuid is a typeinfo index in the specified typelib */ /* if clear oGuid is a typeinfo index in the specified typelib */
/* bits 24 - 31: TKIND of reference */ /* bits 24 - 31: TKIND of reference */
INT oImpFile; /* offset in the Import File table */ INT oImpFile; /* offset in the Import File table */
INT oGuid; /* offset in Guid table or typeinfo index (see bit 16 of res0) */ 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 */ /* function description data */
typedef struct { typedef struct {

View file

@ -80,7 +80,7 @@ QueryPathOfRegTypeLib16(
{ {
char xguid[80]; char xguid[80];
char typelibkey[100],pathname[260]; char typelibkey[100],pathname[260];
DWORD plen; LONG plen;
TRACE("\n"); TRACE("\n");

View file

@ -148,7 +148,7 @@ typedef struct tagICreateTypeLib2Impl
const ICreateTypeLib2Vtbl *lpVtbl; const ICreateTypeLib2Vtbl *lpVtbl;
const ITypeLib2Vtbl *lpVtblTypeLib2; const ITypeLib2Vtbl *lpVtblTypeLib2;
ULONG ref; LONG ref;
WCHAR *filename; WCHAR *filename;
@ -174,7 +174,7 @@ typedef struct tagICreateTypeInfo2Impl
const ICreateTypeInfo2Vtbl *lpVtbl; const ICreateTypeInfo2Vtbl *lpVtbl;
const ITypeInfo2Vtbl *lpVtblTypeInfo2; const ITypeInfo2Vtbl *lpVtblTypeInfo2;
ULONG ref; LONG ref;
ICreateTypeLib2Impl *typelib; ICreateTypeLib2Impl *typelib;
MSFT_TypeInfoBase *typeinfo; MSFT_TypeInfoBase *typeinfo;
@ -1242,7 +1242,7 @@ static HRESULT WINAPI ICreateTypeInfo2_fnSetTypeFlags(ICreateTypeInfo2 *iface, U
guidoffset = ctl2_alloc_guid(This->typelib, &foo); guidoffset = ctl2_alloc_guid(This->typelib, &foo);
if (guidoffset == -1) return E_OUTOFMEMORY; if (guidoffset == -1) return E_OUTOFMEMORY;
impinfo.res0 = 0x03010000; impinfo.flags = TKIND_INTERFACE << 24 | MSFT_IMPINFO_OFFSET_IS_GUID;
impinfo.oImpFile = fileoffset; impinfo.oImpFile = fileoffset;
impinfo.oGuid = guidoffset; impinfo.oGuid = guidoffset;
ctl2_alloc_importinfo(This->typelib, &impinfo); ctl2_alloc_importinfo(This->typelib, &impinfo);

View file

@ -82,7 +82,6 @@ static inline HRESULT VARIANT_Coerce(VARIANTARG* pd, LCID lcid, USHORT wFlags,
{ {
HRESULT res = DISP_E_TYPEMISMATCH; HRESULT res = DISP_E_TYPEMISMATCH;
VARTYPE vtFrom = V_TYPE(ps); VARTYPE vtFrom = V_TYPE(ps);
BOOL bIgnoreOverflow = FALSE;
DWORD dwFlags = 0; DWORD dwFlags = 0;
TRACE("(%p->(%s%s),0x%08lx,0x%04x,%p->(%s%s),%s%s)\n", pd, debugstr_VT(pd), 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) if (vtFrom == VT_INT)
vtFrom = VT_I4; vtFrom = VT_I4;
else if (vtFrom == VT_UINT) else if (vtFrom == VT_UINT)
{
vtFrom = VT_UI4; vtFrom = VT_UI4;
if (vt == VT_I4)
bIgnoreOverflow = TRUE;
}
if (vt == vtFrom) if (vt == vtFrom)
return VariantCopy(pd, ps); 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_EMPTY: V_I1(pd) = 0; return S_OK;
case VT_I2: return VarI1FromI2(V_I2(ps), &V_I1(pd)); case VT_I2: return VarI1FromI2(V_I2(ps), &V_I1(pd));
case VT_I4: return VarI1FromI4(V_I4(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_UI2: return VarI1FromUI2(V_UI2(ps), &V_I1(pd));
case VT_UI4: return VarI1FromUI4(V_UI4(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_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_I1: return VarI2FromI1(V_I1(ps), &V_I2(pd));
case VT_I4: return VarI2FromI4(V_I4(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_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_UI4: return VarI2FromUI4(V_UI4(ps), &V_I2(pd));
case VT_I8: return VarI2FromI8(V_I8(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_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_I2: return VarI4FromI2(V_I2(ps), &V_I4(pd));
case VT_UI1: return VarI4FromUI1(V_UI1(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_UI2: return VarI4FromUI2(V_UI2(ps), &V_I4(pd));
case VT_UI4: case VT_UI4: V_I4(pd) = V_UI4(ps); return S_OK;
if (bIgnoreOverflow)
{
V_VT(pd) = VT_I4;
V_I4(pd) = V_I4(ps);
return S_OK;
}
return VarI4FromUI4(V_UI4(ps), &V_I4(pd));
case VT_I8: return VarI4FromI8(V_I8(ps), &V_I4(pd)); case VT_I8: return VarI4FromI8(V_I8(ps), &V_I4(pd));
case VT_UI8: return VarI4FromUI8(V_UI8(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_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) switch (vtFrom)
{ {
case VT_EMPTY: V_UI1(pd) = 0; return S_OK; 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_I2: return VarUI1FromI2(V_I2(ps), &V_UI1(pd));
case VT_I4: return VarUI1FromI4(V_I4(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_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_EMPTY: V_UI2(pd) = 0; return S_OK;
case VT_I1: return VarUI2FromI1(V_I1(ps), &V_UI2(pd)); 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_I4: return VarUI2FromI4(V_I4(ps), &V_UI2(pd));
case VT_UI1: return VarUI2FromUI1(V_UI1(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_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_EMPTY: V_UI4(pd) = 0; return S_OK;
case VT_I1: return VarUI4FromI1(V_I1(ps), &V_UI4(pd)); case VT_I1: return VarUI4FromI1(V_I1(ps), &V_UI4(pd));
case VT_I2: return VarUI4FromI2(V_I2(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_UI1: return VarUI4FromUI1(V_UI1(ps), &V_UI4(pd));
case VT_UI2: return VarUI4FromUI2(V_UI2(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_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_UI1: return VarUI8FromUI1(V_UI1(ps), &V_UI8(pd));
case VT_UI2: return VarUI8FromUI2(V_UI2(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_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_R4: return VarUI8FromR4(V_R4(ps), &V_UI8(pd));
case VT_R8: return VarUI8FromR8(V_R8(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_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_UI1: return VarI8FromUI1(V_UI1(ps), &V_I8(pd));
case VT_UI2: return VarI8FromUI2(V_UI2(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_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_R4: return VarI8FromR4(V_R4(ps), &V_I8(pd));
case VT_R8: return VarI8FromR8(V_R8(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_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)
{ {

View file

@ -5258,6 +5258,19 @@ static HRESULT VARIANT_BstrFromReal(DOUBLE dblIn, LCID lcid, ULONG dwFlags,
return E_INVALIDARG; return E_INVALIDARG;
sprintfW( buff, lpszFormat, dblIn ); 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)); TRACE("created string %s\n", debugstr_w(buff));
if (dwFlags & LOCALE_USE_NLS) if (dwFlags & LOCALE_USE_NLS)
{ {