From 22d351dde070216332c10010c2641e0ba2a11ff4 Mon Sep 17 00:00:00 2001 From: Amine Khaldi Date: Tue, 17 Nov 2015 11:59:11 +0000 Subject: [PATCH] [OLEAUT32] Sync with Wine Staging 1.7.55. CORE-10536 svn path=/trunk/; revision=69915 --- reactos/dll/win32/oleaut32/CMakeLists.txt | 2 +- reactos/dll/win32/oleaut32/oleaut.c | 6 +- reactos/dll/win32/oleaut32/olepicture.c | 15 ++ reactos/dll/win32/oleaut32/tmarshal.c | 247 ++++++++++++++++------ reactos/dll/win32/oleaut32/typelib.c | 138 ++++++------ reactos/dll/win32/oleaut32/typelib.h | 2 +- reactos/dll/win32/oleaut32/usrmarshal.c | 7 +- reactos/dll/win32/oleaut32/variant.c | 4 +- reactos/dll/win32/oleaut32/vartype.c | 8 +- reactos/media/doc/README.WINE | 2 +- 10 files changed, 281 insertions(+), 150 deletions(-) diff --git a/reactos/dll/win32/oleaut32/CMakeLists.txt b/reactos/dll/win32/oleaut32/CMakeLists.txt index 47a35438c14..131285244c2 100644 --- a/reactos/dll/win32/oleaut32/CMakeLists.txt +++ b/reactos/dll/win32/oleaut32/CMakeLists.txt @@ -58,6 +58,6 @@ add_dependencies(oleaut32 oleaut32_idlheader) set_module_type(oleaut32 win32dll) target_link_libraries(oleaut32 wine wineldr uuid ${PSEH_LIB}) add_delay_importlibs(oleaut32 comctl32 urlmon windowscodecs) -add_importlibs(oleaut32 ole32 rpcrt4 user32 gdi32 advapi32 msvcrt kernel32 ntdll) +add_importlibs(oleaut32 ole32 rpcrt4 user32 gdi32 advapi32 kernel32_vista msvcrt kernel32 ntdll) add_pch(oleaut32 precomp.h SOURCE) add_cd_file(TARGET oleaut32 DESTINATION reactos/system32 FOR all) diff --git a/reactos/dll/win32/oleaut32/oleaut.c b/reactos/dll/win32/oleaut32/oleaut.c index 961f40c856c..9e4add0c358 100644 --- a/reactos/dll/win32/oleaut32/oleaut.c +++ b/reactos/dll/win32/oleaut32/oleaut.c @@ -484,7 +484,7 @@ static const WCHAR *pdelimiter = &_delimiter[0]; * Success: S_OK. * Failure: HRESULT code. */ -HRESULT WINAPI RegisterActiveObject( +HRESULT WINAPI DECLSPEC_HOTPATCH RegisterActiveObject( LPUNKNOWN punk,REFCLSID rcid,DWORD dwFlags,LPDWORD pdwRegister ) { WCHAR guidbuf[80]; @@ -523,7 +523,7 @@ HRESULT WINAPI RegisterActiveObject( * Success: S_OK. * Failure: HRESULT code. */ -HRESULT WINAPI RevokeActiveObject(DWORD xregister,LPVOID reserved) +HRESULT WINAPI DECLSPEC_HOTPATCH RevokeActiveObject(DWORD xregister,LPVOID reserved) { LPRUNNINGOBJECTTABLE runobtable; HRESULT ret; @@ -550,7 +550,7 @@ HRESULT WINAPI RevokeActiveObject(DWORD xregister,LPVOID reserved) * Success: S_OK. * Failure: HRESULT code. */ -HRESULT WINAPI GetActiveObject(REFCLSID rcid,LPVOID preserved,LPUNKNOWN *ppunk) +HRESULT WINAPI DECLSPEC_HOTPATCH GetActiveObject(REFCLSID rcid,LPVOID preserved,LPUNKNOWN *ppunk) { WCHAR guidbuf[80]; HRESULT ret; diff --git a/reactos/dll/win32/oleaut32/olepicture.c b/reactos/dll/win32/oleaut32/olepicture.c index 33832afc20f..2329d4cb7fe 100644 --- a/reactos/dll/win32/oleaut32/olepicture.c +++ b/reactos/dll/win32/oleaut32/olepicture.c @@ -1190,6 +1190,8 @@ static HRESULT OLEPictureImpl_LoadIcon(OLEPictureImpl *This, BYTE *xbuf, ULONG x HDC hdcRef; int i; + TRACE("(this %p, xbuf %p, xread %u)\n", This, xbuf, xread); + /* FIXME("icon.idReserved=%d\n",cifd->idReserved); FIXME("icon.idType=%d\n",cifd->idType); @@ -1206,6 +1208,13 @@ static HRESULT OLEPictureImpl_LoadIcon(OLEPictureImpl *This, BYTE *xbuf, ULONG x FIXME("[%d] dwDIBOffset %d\n",i,cifd->idEntries[i].dwDIBOffset); } */ + + /* Need at least one icon to do something. */ + if (!cifd->idCount) + { + ERR("Invalid icon count of zero.\n"); + return E_FAIL; + } i=0; /* If we have more than one icon, try to find the best. * this currently means '32 pixel wide'. @@ -1217,6 +1226,12 @@ static HRESULT OLEPictureImpl_LoadIcon(OLEPictureImpl *This, BYTE *xbuf, ULONG x } if (i==cifd->idCount) i=0; } + if (xread < cifd->idEntries[i].dwDIBOffset + cifd->idEntries[i].dwDIBSize) + { + ERR("Icon data address %u is over %u bytes available.\n", + cifd->idEntries[i].dwDIBOffset + cifd->idEntries[i].dwDIBSize, xread); + return E_FAIL; + } if (cifd->idType == 2) { LPBYTE buf = HeapAlloc(GetProcessHeap(), 0, cifd->idEntries[i].dwDIBSize + 4); diff --git a/reactos/dll/win32/oleaut32/tmarshal.c b/reactos/dll/win32/oleaut32/tmarshal.c index 6381f1c1212..c0483fd9d72 100644 --- a/reactos/dll/win32/oleaut32/tmarshal.c +++ b/reactos/dll/win32/oleaut32/tmarshal.c @@ -469,7 +469,6 @@ static HRESULT num_of_funcs(ITypeInfo *tinfo, unsigned int *num, #ifdef __i386__ #include "pshpack1.h" - typedef struct _TMAsmProxy { DWORD lealeax; BYTE pushleax; @@ -481,7 +480,30 @@ typedef struct _TMAsmProxy { WORD bytestopop; WORD nop; } TMAsmProxy; +#include "poppack.h" + +#elif defined(__x86_64__) +#include "pshpack1.h" +typedef struct _TMAsmProxy { + BYTE pushq_rbp; + BYTE movq_rsp_rbp[3]; + DWORD subq_0x20_rsp; + DWORD movq_rcx_0x10rbp; + DWORD movq_rdx_0x18rbp; + DWORD movq_r8_0x20rbp; + DWORD movq_r9_0x28rbp; + BYTE movq_rcx[3]; + DWORD nr; + DWORD leaq_0x10rbp_rdx; + WORD movq_rax; + void *xcall; + WORD callq_rax; + BYTE movq_rbp_rsp[3]; + BYTE popq_rbp; + BYTE ret; + DWORD nop; +} TMAsmProxy; #include "poppack.h" #else /* __i386__ */ @@ -617,42 +639,51 @@ static const IRpcProxyBufferVtbl tmproxyvtable = { TMProxyImpl_Disconnect }; -/* how much space do we use on stack in DWORD steps. */ +/* how much space do we use on stack in DWORD_PTR steps. */ static int _argsize(TYPEDESC *tdesc, ITypeInfo *tinfo) { + DWORD ret; switch (tdesc->vt) { case VT_I8: case VT_UI8: - return 8/sizeof(DWORD); + ret = 8; + break; case VT_R8: - return sizeof(double)/sizeof(DWORD); + ret = sizeof(double); + break; case VT_CY: - return sizeof(CY)/sizeof(DWORD); + ret = sizeof(CY); + break; case VT_DATE: - return sizeof(DATE)/sizeof(DWORD); + ret = sizeof(DATE); + break; case VT_DECIMAL: - return (sizeof(DECIMAL)+3)/sizeof(DWORD); + ret = sizeof(DECIMAL); + break; case VT_VARIANT: - return (sizeof(VARIANT)+3)/sizeof(DWORD); + ret = sizeof(VARIANT); + break; case VT_USERDEFINED: { ITypeInfo *tinfo2; TYPEATTR *tattr; HRESULT hres; - DWORD ret; hres = ITypeInfo_GetRefTypeInfo(tinfo,tdesc->u.hreftype,&tinfo2); if (FAILED(hres)) return 0; /* should fail critically in serialize_param */ ITypeInfo_GetTypeAttr(tinfo2,&tattr); - ret = (tattr->cbSizeInstance+3)/sizeof(DWORD); + ret = tattr->cbSizeInstance; ITypeInfo_ReleaseTypeAttr(tinfo2, tattr); ITypeInfo_Release(tinfo2); - return ret; + break; } default: - return 1; + ret = sizeof(DWORD_PTR); + break; } + + return (ret + sizeof(DWORD_PTR) - 1) / sizeof(DWORD_PTR); } /* how much space do we use on the heap (in bytes) */ @@ -701,7 +732,7 @@ _xsize(const TYPEDESC *td, ITypeInfo *tinfo) { return ret; } default: - return 4; + return sizeof(DWORD_PTR); } } @@ -720,7 +751,7 @@ serialize_param( BOOL debugout, BOOL dealloc, TYPEDESC *tdesc, - DWORD *arg, + DWORD_PTR *arg, marshal_state *buf) { HRESULT hres = S_OK; @@ -739,7 +770,7 @@ serialize_param( case VT_R8: case VT_CY: hres = S_OK; - if (debugout) TRACE_(olerelay)("%x%x\n",arg[0],arg[1]); + if (debugout) TRACE_(olerelay)("%s\n", wine_dbgstr_longlong(*(ULONGLONG *)arg)); if (writeit) hres = xbuf_add(buf,(LPBYTE)arg,8); return hres; @@ -750,7 +781,7 @@ serialize_param( case VT_R4: case VT_UI4: hres = S_OK; - if (debugout) TRACE_(olerelay)("%x\n",*arg); + if (debugout) TRACE_(olerelay)("%x\n", *(DWORD *)arg); if (writeit) hres = xbuf_add(buf,(LPBYTE)arg,sizeof(DWORD)); return hres; @@ -758,14 +789,14 @@ serialize_param( case VT_UI2: case VT_BOOL: hres = S_OK; - if (debugout) TRACE_(olerelay)("%04x\n",*arg & 0xffff); + if (debugout) TRACE_(olerelay)("%04x\n", *(WORD *)arg); if (writeit) hres = xbuf_add(buf,(LPBYTE)arg,sizeof(DWORD)); return hres; case VT_I1: case VT_UI1: hres = S_OK; - if (debugout) TRACE_(olerelay)("%02x\n",*arg & 0xff); + if (debugout) TRACE_(olerelay)("%02x\n", *(BYTE *)arg); if (writeit) hres = xbuf_add(buf,(LPBYTE)arg,sizeof(DWORD)); return hres; @@ -835,7 +866,9 @@ serialize_param( return hres; } ITypeInfo_GetTypeAttr(tinfo2,&tattr); - derefhere = (tattr->typekind != TKIND_DISPATCH && tattr->typekind != TKIND_INTERFACE); + derefhere = (tattr->typekind != TKIND_DISPATCH && + tattr->typekind != TKIND_INTERFACE && + tattr->typekind != TKIND_COCLASS); } break; case TKIND_ENUM: /* confirmed */ @@ -843,6 +876,7 @@ serialize_param( break; case TKIND_DISPATCH: /* will be done in VT_USERDEFINED case */ case TKIND_INTERFACE: /* will be done in VT_USERDEFINED case */ + case TKIND_COCLASS: /* will be done in VT_USERDEFINED case */ derefhere=FALSE; break; default: @@ -865,19 +899,19 @@ serialize_param( if (debugout) TRACE_(olerelay)("NULL"); return S_OK; } - hres = serialize_param(tinfo,writeit,debugout,dealloc,tdesc->u.lptdesc,(DWORD*)*arg,buf); + hres = serialize_param(tinfo,writeit,debugout,dealloc,tdesc->u.lptdesc,(DWORD_PTR *)*arg,buf); if (derefhere && dealloc) HeapFree(GetProcessHeap(),0,(LPVOID)*arg); return hres; } case VT_UNKNOWN: - if (debugout) TRACE_(olerelay)("unk(0x%x)",*arg); + if (debugout) TRACE_(olerelay)("unk(0x%lx)", *arg); if (writeit) hres = _marshal_interface(buf,&IID_IUnknown,(LPUNKNOWN)*arg); if (dealloc && *(IUnknown **)arg) IUnknown_Release((LPUNKNOWN)*arg); return hres; case VT_DISPATCH: - if (debugout) TRACE_(olerelay)("idisp(0x%x)",*arg); + if (debugout) TRACE_(olerelay)("idisp(0x%lx)", *arg); if (writeit) hres = _marshal_interface(buf,&IID_IDispatch,(LPUNKNOWN)*arg); if (dealloc && *(IUnknown **)arg) @@ -904,6 +938,36 @@ serialize_param( if (dealloc) IUnknown_Release((LPUNKNOWN)arg); break; + case TKIND_COCLASS: { + GUID iid = tattr->guid; + unsigned int i; + int type_flags; + + for(i = 0; i < tattr->cImplTypes; i++) { + if(SUCCEEDED(ITypeInfo_GetImplTypeFlags(tinfo2, i, &type_flags)) && + type_flags == (IMPLTYPEFLAG_FSOURCE|IMPLTYPEFLAG_FDEFAULT)) { + ITypeInfo *tinfo3; + TYPEATTR *tattr2; + HREFTYPE href; + if(FAILED(ITypeInfo_GetRefTypeOfImplType(tinfo2, i, &href))) + break; + if(FAILED(ITypeInfo_GetRefTypeInfo(tinfo2, href, &tinfo3))) + break; + if(SUCCEEDED(ITypeInfo_GetTypeAttr(tinfo3, &tattr2))) { + iid = tattr2->guid; + ITypeInfo_ReleaseTypeAttr(tinfo3, tattr2); + } + ITypeInfo_Release(tinfo3); + break; + } + } + + if(writeit) + hres=_marshal_interface(buf, &iid, (LPUNKNOWN)arg); + if(dealloc) + IUnknown_Release((LPUNKNOWN)arg); + break; + } case TKIND_RECORD: { int i; if (debugout) TRACE_(olerelay)("{"); @@ -925,7 +989,7 @@ serialize_param( debugout, dealloc, tdesc2, - (DWORD*)(((LPBYTE)arg)+vdesc->u.oInst), + (DWORD_PTR *)(((LPBYTE)arg)+vdesc->u.oInst), buf ); ITypeInfo_ReleaseVarDesc(tinfo2, vdesc); @@ -942,7 +1006,7 @@ serialize_param( break; case TKIND_ENUM: hres = S_OK; - if (debugout) TRACE_(olerelay)("%x",*arg); + if (debugout) TRACE_(olerelay)("%x", *(DWORD *)arg); if (writeit) hres = xbuf_add(buf,(LPBYTE)arg,sizeof(DWORD)); break; @@ -968,7 +1032,7 @@ serialize_param( if (debugout) TRACE_(olerelay)("["); for (i=0;itdescElem, tinfo) ? (LPBYTE) *arg : (LPBYTE) arg; - hres = serialize_param(tinfo, writeit, debugout, dealloc, &adesc->tdescElem, (DWORD*)((LPBYTE)base+i*_xsize(&adesc->tdescElem, tinfo)), buf); + hres = serialize_param(tinfo, writeit, debugout, dealloc, &adesc->tdescElem, (DWORD_PTR *)((LPBYTE)base+i*_xsize(&adesc->tdescElem, tinfo)), buf); if (hres) return hres; if (debugout && (itypekind != TKIND_DISPATCH && tattr->typekind != TKIND_INTERFACE); + derefhere = (tattr->typekind != TKIND_DISPATCH && + tattr->typekind != TKIND_INTERFACE && + tattr->typekind != TKIND_COCLASS); } break; case TKIND_ENUM: /* confirmed */ @@ -1121,6 +1187,7 @@ deserialize_param( break; case TKIND_DISPATCH: /* will be done in VT_USERDEFINED case */ case TKIND_INTERFACE: /* will be done in VT_USERDEFINED case */ + case TKIND_COCLASS: /* will be done in VT_USERDEFINED case */ derefhere=FALSE; break; default: @@ -1149,17 +1216,17 @@ deserialize_param( if (alloc) { /* Allocate space for the referenced struct */ if (derefhere) - *arg=(DWORD)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,_xsize(tdesc->u.lptdesc, tinfo)); + *arg=(DWORD_PTR)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,_xsize(tdesc->u.lptdesc, tinfo)); } if (derefhere) - return deserialize_param(tinfo, readit, debugout, alloc, tdesc->u.lptdesc, (LPDWORD)*arg, buf); + return deserialize_param(tinfo, readit, debugout, alloc, tdesc->u.lptdesc, (DWORD_PTR *)*arg, buf); else return deserialize_param(tinfo, readit, debugout, alloc, tdesc->u.lptdesc, arg, buf); } case VT_UNKNOWN: /* FIXME: UNKNOWN is unknown ..., but allocate 4 byte for it */ if (alloc) - *arg=(DWORD)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(DWORD)); + *arg=(DWORD_PTR)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(DWORD_PTR)); hres = S_OK; if (readit) hres = _unmarshal_interface(buf,&IID_IUnknown,(LPUNKNOWN*)arg); @@ -1195,6 +1262,34 @@ deserialize_param( if (readit) hres = _unmarshal_interface(buf,&(tattr->guid),(LPUNKNOWN*)arg); break; + case TKIND_COCLASS: { + GUID iid = tattr->guid; + unsigned int i; + int type_flags; + + for(i = 0; i < tattr->cImplTypes; i++) { + if(SUCCEEDED(ITypeInfo_GetImplTypeFlags(tinfo2, i, &type_flags)) && + type_flags == (IMPLTYPEFLAG_FSOURCE|IMPLTYPEFLAG_FDEFAULT)) { + ITypeInfo *tinfo3; + TYPEATTR *tattr2; + HREFTYPE href; + if(FAILED(ITypeInfo_GetRefTypeOfImplType(tinfo2, i, &href))) + break; + if(FAILED(ITypeInfo_GetRefTypeInfo(tinfo2, href, &tinfo3))) + break; + if(SUCCEEDED(ITypeInfo_GetTypeAttr(tinfo3, &tattr2))) { + iid = tattr2->guid; + ITypeInfo_ReleaseTypeAttr(tinfo3, tattr2); + } + ITypeInfo_Release(tinfo3); + break; + } + } + + if(readit) + hres = _unmarshal_interface(buf, &iid, (LPUNKNOWN*)arg); + break; + } case TKIND_RECORD: { int i; @@ -1215,7 +1310,7 @@ deserialize_param( debugout, alloc, &vdesc->elemdescVar.tdesc, - (DWORD*)(((LPBYTE)arg)+vdesc->u.oInst), + (DWORD_PTR *)(((LPBYTE)arg)+vdesc->u.oInst), buf ); ITypeInfo_ReleaseVarDesc(tinfo2, vdesc); @@ -1232,7 +1327,7 @@ deserialize_param( hres = xbuf_get(buf,(LPBYTE)arg,sizeof(DWORD)); if (hres) ERR("Failed to read enum (4 byte)\n"); } - if (debugout) TRACE_(olerelay)("%x",*arg); + if (debugout) TRACE_(olerelay)("%x", *(DWORD *)arg); break; default: ERR("Unhandled typekind %d\n",tattr->typekind); @@ -1258,7 +1353,7 @@ deserialize_param( if (_passbyref(&adesc->tdescElem, tinfo)) { base = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,_xsize(tdesc->u.lptdesc, tinfo) * arrsize); - *arg = (DWORD) base; + *arg = (DWORD_PTR)base; } for (i=0;itdescElem, - (DWORD*)(base + i*_xsize(&adesc->tdescElem, tinfo)), + (DWORD_PTR *)(base + i*_xsize(&adesc->tdescElem, tinfo)), buf ); return S_OK; @@ -1397,7 +1492,7 @@ static inline BOOL is_out_elem(const ELEMDESC *elem) static DWORD WINAPI xCall(int method, void **args) { TMProxyImpl *tpinfo = args[0]; - DWORD *xargs; + DWORD_PTR *xargs; const FUNCDESC *fdesc; HRESULT hres; int i; @@ -1457,7 +1552,7 @@ static DWORD WINAPI xCall(int method, void **args) if (nrofnames > sizeof(names)/sizeof(names[0])) ERR("Need more names!\n"); - xargs = (DWORD *)(args + 1); + xargs = (DWORD_PTR *)(args + 1); for (i=0;icParams;i++) { ELEMDESC *elem = fdesc->lprgelemdescParam+i; if (TRACE_ON(olerelay)) { @@ -1524,7 +1619,7 @@ static DWORD WINAPI xCall(int method, void **args) buf.curoff = 0; /* generic deserializer using typelib description */ - xargs = (DWORD *)(args + 1); + xargs = (DWORD_PTR *)(args + 1); status = S_OK; for (i=0;icParams;i++) { ELEMDESC *elem = fdesc->lprgelemdescParam+i; @@ -1785,11 +1880,7 @@ static HRESULT init_proxy_entry_point(TMProxyImpl *proxy, unsigned int num) /* nrofargs including This */ int nrofargs = 1; ITypeInfo *tinfo2; - -#ifdef __i386__ TMAsmProxy *xasm = proxy->asmstubs + num; -#endif - HRESULT hres; const FUNCDESC *fdesc; @@ -1824,6 +1915,34 @@ static HRESULT init_proxy_entry_point(TMProxyImpl *proxy, unsigned int num) xasm->bytestopop = nrofargs * 4; xasm->nop = 0x9090; proxy->lpvtbl[fdesc->oVft / sizeof(void *)] = xasm; + +#elif defined(__x86_64__) + + xasm->pushq_rbp = 0x55; /* pushq %rbp */ + xasm->movq_rsp_rbp[0] = 0x48; /* movq %rsp,%rbp */ + xasm->movq_rsp_rbp[1] = 0x89; + xasm->movq_rsp_rbp[2] = 0xe5; + xasm->subq_0x20_rsp = 0x20ec8348; /* subq 0x20,%rsp */ + xasm->movq_rcx_0x10rbp = 0x104d8948; /* movq %rcx,0x10(%rbp) */ + xasm->movq_rdx_0x18rbp = 0x18558948; /* movq %rdx,0x18(%rbp) */ + xasm->movq_r8_0x20rbp = 0x2045894c; /* movq %r8,0x20(%rbp) */ + xasm->movq_r9_0x28rbp = 0x284d894c; /* movq %r9,0x28(%rbp) */ + xasm->movq_rcx[0] = 0x48; /* movq ,%rcx */ + xasm->movq_rcx[1] = 0xc7; + xasm->movq_rcx[2] = 0xc1; + xasm->nr = num; + xasm->leaq_0x10rbp_rdx = 0x10558d48; /* leaq 0x10(%rbp),%rdx */ + xasm->movq_rax = 0xb848; /* movq ,%rax */ + xasm->xcall = xCall; + xasm->callq_rax = 0xd0ff; /* callq *%rax */ + xasm->movq_rbp_rsp[0] = 0x48; /* movq %rbp,%rsp */ + xasm->movq_rbp_rsp[1] = 0x89; + xasm->movq_rbp_rsp[2] = 0xec; + xasm->popq_rbp = 0x5d; /* popq %rbp */ + xasm->ret = 0xc3; /* ret */ + xasm->nop = 0x90909090; /* nop */ + proxy->lpvtbl[fdesc->oVft / sizeof(void *)] = xasm; + #else FIXME("not implemented on non i386\n"); return E_FAIL; @@ -2050,12 +2169,13 @@ static HRESULT WINAPI TMStubImpl_Invoke( LPRPCSTUBBUFFER iface, RPCOLEMESSAGE* xmsg,IRpcChannelBuffer*rpcchanbuf) { -#ifdef __i386__ +#if defined(__i386__) || defined(__x86_64__) int i; const FUNCDESC *fdesc; TMStubImpl *This = impl_from_IRpcStubBuffer(iface); HRESULT hres; - DWORD *args = NULL, res, *xargs, nrofargs; + DWORD_PTR *args = NULL, *xargs; + DWORD res, nrofargs; marshal_state buf; UINT nrofnames = 0; BSTR names[10]; @@ -2120,7 +2240,7 @@ TMStubImpl_Invoke( nrofargs = 0; for (i=0;icParams;i++) nrofargs += _argsize(&fdesc->lprgelemdescParam[i].tdesc, tinfo); - args = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,(nrofargs+1)*sizeof(DWORD)); + args = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (nrofargs+1)*sizeof(DWORD_PTR)); if (!args) { hres = E_OUTOFMEMORY; @@ -2148,12 +2268,12 @@ TMStubImpl_Invoke( } } - args[0] = (DWORD)This->pUnk; + args[0] = (DWORD_PTR)This->pUnk; __TRY { res = _invoke( - (*((FARPROC**)args[0]))[fdesc->oVft/4], + (*((FARPROC**)args[0]))[fdesc->oVft / sizeof(DWORD_PTR)], fdesc->callconv, (xargs-args), args @@ -2270,6 +2390,7 @@ PSFacBuf_CreateStub( ITypeInfo *tinfo; TMStubImpl *stub; TYPEATTR *typeattr; + IUnknown *obj; TRACE("(%s,%p,%p)\n",debugstr_guid(riid),pUnkServer,ppStub); @@ -2279,16 +2400,26 @@ PSFacBuf_CreateStub( return hres; } + /* FIXME: This is not exactly right. We should probably call QI later. */ + hres = IUnknown_QueryInterface(pUnkServer, riid, (void**)&obj); + if (FAILED(hres)) { + WARN("Could not get %s iface: %08x\n", debugstr_guid(riid), hres); + obj = pUnkServer; + IUnknown_AddRef(obj); + } + stub = CoTaskMemAlloc(sizeof(TMStubImpl)); - if (!stub) + if (!stub) { + IUnknown_Release(obj); return E_OUTOFMEMORY; + } stub->IRpcStubBuffer_iface.lpVtbl = &tmstubvtbl; stub->ref = 1; stub->tinfo = tinfo; stub->dispatch_stub = NULL; stub->dispatch_derivative = FALSE; stub->iid = *riid; - hres = IRpcStubBuffer_Connect(&stub->IRpcStubBuffer_iface,pUnkServer); + hres = IRpcStubBuffer_Connect(&stub->IRpcStubBuffer_iface, obj); *ppStub = &stub->IRpcStubBuffer_iface; TRACE("IRpcStubBuffer: %p\n", stub); if (hres) @@ -2303,6 +2434,7 @@ PSFacBuf_CreateStub( ITypeInfo_ReleaseTypeAttr(tinfo, typeattr); } + IUnknown_Release(obj); return hres; } @@ -2314,17 +2446,12 @@ static const IPSFactoryBufferVtbl psfacbufvtbl = { PSFacBuf_CreateStub }; -/* This is the whole PSFactoryBuffer object, just the vtableptr */ -static const IPSFactoryBufferVtbl *lppsfac = &psfacbufvtbl; +static IPSFactoryBuffer psfac = { &psfacbufvtbl }; /*********************************************************************** * TMARSHAL_DllGetClassObject */ -HRESULT TMARSHAL_DllGetClassObject(REFCLSID rclsid, REFIID iid,LPVOID *ppv) +HRESULT TMARSHAL_DllGetClassObject(REFCLSID rclsid, REFIID iid, void **ppv) { - if (IsEqualIID(iid,&IID_IPSFactoryBuffer)) { - *ppv = &lppsfac; - return S_OK; - } - return E_NOINTERFACE; + return IPSFactoryBuffer_QueryInterface(&psfac, iid, ppv); } diff --git a/reactos/dll/win32/oleaut32/typelib.c b/reactos/dll/win32/oleaut32/typelib.c index 79aa8b3268e..2a45429b29b 100644 --- a/reactos/dll/win32/oleaut32/typelib.c +++ b/reactos/dll/win32/oleaut32/typelib.c @@ -57,67 +57,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(ole); WINE_DECLARE_DEBUG_CHANNEL(typelib); -#ifdef __REACTOS__ -/* FIXME: Vista+ */ -#define STATUS_SUCCESS ((NTSTATUS)0x00000000) -static BOOL WINAPI GetFileInformationByHandleEx( HANDLE handle, FILE_INFO_BY_HANDLE_CLASS class, - LPVOID info, DWORD size ) -{ - NTSTATUS status; - IO_STATUS_BLOCK io; - - switch (class) - { - case FileBasicInfo: - case FileStandardInfo: - case FileRenameInfo: - case FileDispositionInfo: - case FileAllocationInfo: - case FileEndOfFileInfo: - case FileStreamInfo: - case FileCompressionInfo: - case FileAttributeTagInfo: - case FileIoPriorityHintInfo: - case FileRemoteProtocolInfo: - case FileFullDirectoryInfo: - case FileFullDirectoryRestartInfo: - case FileStorageInfo: - case FileAlignmentInfo: - case FileIdInfo: - case FileIdExtdDirectoryInfo: - case FileIdExtdDirectoryRestartInfo: - FIXME( "%p, %u, %p, %u\n", handle, class, info, size ); - SetLastError( ERROR_CALL_NOT_IMPLEMENTED ); - return FALSE; - - case FileNameInfo: - status = NtQueryInformationFile( handle, &io, info, size, FileNameInformation ); - if (status != STATUS_SUCCESS) - { - SetLastError( RtlNtStatusToDosError( status ) ); - return FALSE; - } - return TRUE; - - case FileIdBothDirectoryRestartInfo: - case FileIdBothDirectoryInfo: - status = NtQueryDirectoryFile( handle, NULL, NULL, NULL, &io, info, size, - FileIdBothDirectoryInformation, FALSE, NULL, - (class == FileIdBothDirectoryRestartInfo) ); - if (status != STATUS_SUCCESS) - { - SetLastError( RtlNtStatusToDosError( status ) ); - return FALSE; - } - return TRUE; - - default: - SetLastError( ERROR_INVALID_PARAMETER ); - return FALSE; - } -} -#endif - typedef struct { WORD offset; @@ -6442,15 +6381,15 @@ static double (* const call_double_method)(void*,int,const DWORD*,int*) = (void * Invokes a method, or accesses a property of an object, that implements the * interface described by the type description. */ -DWORD -_invoke(FARPROC func,CALLCONV callconv, int nrargs, DWORD *args) { +DWORD _invoke(FARPROC func, CALLCONV callconv, int nrargs, DWORD_PTR *args) +{ DWORD res; int stack_offset; if (TRACE_ON(ole)) { int i; TRACE("Calling %p(",func); - for (i=0;i 30) TRACE("..."); TRACE(")\n"); } @@ -6458,7 +6397,7 @@ _invoke(FARPROC func,CALLCONV callconv, int nrargs, DWORD *args) { switch (callconv) { case CC_STDCALL: case CC_CDECL: - res = call_method( func, nrargs, args, &stack_offset ); + res = call_method(func, nrargs, (DWORD *)args, &stack_offset); break; default: FIXME("unsupported calling convention %d\n",callconv); @@ -6515,6 +6454,34 @@ __ASM_GLOBAL_FUNC( call_method, /* same function but returning floating point */ static double (CDECL * const call_double_method)(void*,int,const DWORD_PTR*) = (void *)call_method; +DWORD _invoke(FARPROC func, CALLCONV callconv, int nrargs, DWORD_PTR *args) +{ + DWORD res; + + if (TRACE_ON(ole)) + { + int i; + TRACE("Calling %p(", func); + for (i=0; i 30) TRACE("..."); + TRACE(")\n"); + } + + switch (callconv) { + case CC_STDCALL: + case CC_CDECL: + res = call_method(func, nrargs, args); + break; + default: + FIXME("unsupported calling convention %d\n", callconv); + res = -1; + break; + } + + TRACE("returns %08x\n", res); + return res; +} + #endif /* __x86_64__ */ static HRESULT userdefined_to_variantvt(ITypeInfo *tinfo, const TYPEDESC *tdesc, VARTYPE *vt) @@ -6652,13 +6619,13 @@ static HRESULT typedescvt_to_variantvt(ITypeInfo *tinfo, const TYPEDESC *tdesc, return hr; } -static HRESULT get_iface_guid(ITypeInfo *tinfo, const TYPEDESC *tdesc, GUID *guid) +static HRESULT get_iface_guid(ITypeInfo *tinfo, HREFTYPE href, GUID *guid) { ITypeInfo *tinfo2; TYPEATTR *tattr; HRESULT hres; - hres = ITypeInfo_GetRefTypeInfo(tinfo, tdesc->u.hreftype, &tinfo2); + hres = ITypeInfo_GetRefTypeInfo(tinfo, href, &tinfo2); if(FAILED(hres)) return hres; @@ -6670,7 +6637,7 @@ static HRESULT get_iface_guid(ITypeInfo *tinfo, const TYPEDESC *tdesc, GUID *gui switch(tattr->typekind) { case TKIND_ALIAS: - hres = get_iface_guid(tinfo2, &tattr->tdescAlias, guid); + hres = get_iface_guid(tinfo2, tattr->tdescAlias.u.hreftype, guid); break; case TKIND_INTERFACE: @@ -6678,6 +6645,21 @@ static HRESULT get_iface_guid(ITypeInfo *tinfo, const TYPEDESC *tdesc, GUID *gui *guid = tattr->guid; break; + case TKIND_COCLASS: { + unsigned int i; + int type_flags; + + for(i = 0; i < tattr->cImplTypes; i++) + if(SUCCEEDED(ITypeInfo_GetImplTypeFlags(tinfo2, i, &type_flags)) && + type_flags == (IMPLTYPEFLAG_FSOURCE|IMPLTYPEFLAG_FDEFAULT)) break; + + if(i < tattr->cImplTypes) { + hres = ITypeInfo_GetRefTypeOfImplType(tinfo2, i, &href); + if(SUCCEEDED(hres)) hres = get_iface_guid(tinfo2, href, guid); + } else hres = E_UNEXPECTED; + break; + } + default: ERR("Unexpected typekind %d\n", tattr->typekind); hres = E_UNEXPECTED; @@ -7118,7 +7100,7 @@ static HRESULT WINAPI ITypeInfo_fnInvoke( } V_VT(&rgvarg[i]) = rgvt[i]; } - else if (rgvt[i] == (VT_VARIANT | VT_ARRAY) && func_desc->cParamsOpt < 0 && i == func_desc->cParams-1) + else if ((rgvt[i] == (VT_VARIANT | VT_ARRAY) || rgvt[i] == (VT_VARIANT | VT_ARRAY | VT_BYREF)) && func_desc->cParamsOpt < 0) { SAFEARRAY *a; SAFEARRAYBOUND bound; @@ -7147,7 +7129,10 @@ static HRESULT WINAPI ITypeInfo_fnInvoke( SafeArrayDestroy(a); break; } - V_ARRAY(&rgvarg[i]) = a; + if (rgvt[i] & VT_BYREF) + V_BYREF(&rgvarg[i]) = &a; + else + V_ARRAY(&rgvarg[i]) = a; V_VT(&rgvarg[i]) = rgvt[i]; } else if ((rgvt[i] & VT_BYREF) && !V_ISBYREF(src_arg)) @@ -7193,7 +7178,10 @@ static HRESULT WINAPI ITypeInfo_fnInvoke( IUnknown *userdefined_iface; GUID guid; - hres = get_iface_guid((ITypeInfo*)iface, tdesc->vt == VT_PTR ? tdesc->u.lptdesc : tdesc, &guid); + if (tdesc->vt == VT_PTR) + tdesc = tdesc->u.lptdesc; + + hres = get_iface_guid((ITypeInfo*)iface, tdesc->u.hreftype, &guid); if(FAILED(hres)) break; @@ -7922,19 +7910,19 @@ static HRESULT WINAPI ITypeInfo_fnGetContainingTypeLib( ITypeInfo2 *iface, ITypeLib * *ppTLib, UINT *pIndex) { ITypeInfoImpl *This = impl_from_ITypeInfo2(iface); - + /* If a pointer is null, we simply ignore it, the ATL in particular passes pIndex as 0 */ if (pIndex) { *pIndex=This->index; TRACE("returning pIndex=%d\n", *pIndex); } - + if (ppTLib) { - *ppTLib=(LPTYPELIB )(This->pTypeLib); + *ppTLib = (ITypeLib *)&This->pTypeLib->ITypeLib2_iface; ITypeLib_AddRef(*ppTLib); TRACE("returning ppTLib=%p\n", *ppTLib); } - + return S_OK; } diff --git a/reactos/dll/win32/oleaut32/typelib.h b/reactos/dll/win32/oleaut32/typelib.h index 8914a427d9f..29391154ad1 100644 --- a/reactos/dll/win32/oleaut32/typelib.h +++ b/reactos/dll/win32/oleaut32/typelib.h @@ -598,7 +598,7 @@ extern void heap_free(void *ptr) DECLSPEC_HIDDEN; HRESULT ITypeInfoImpl_GetInternalFuncDesc( ITypeInfo *iface, UINT index, const FUNCDESC **ppFuncDesc ) DECLSPEC_HIDDEN; -extern DWORD _invoke(FARPROC func,CALLCONV callconv, int nrargs, DWORD *args) DECLSPEC_HIDDEN; +extern DWORD _invoke(FARPROC func, CALLCONV callconv, int nrargs, DWORD_PTR *args) DECLSPEC_HIDDEN; HRESULT TMARSHAL_DllGetClassObject(REFCLSID rclsid, REFIID iid,LPVOID *ppv) DECLSPEC_HIDDEN; diff --git a/reactos/dll/win32/oleaut32/usrmarshal.c b/reactos/dll/win32/oleaut32/usrmarshal.c index 0bf2e3b08a3..ef65c07bd8c 100644 --- a/reactos/dll/win32/oleaut32/usrmarshal.c +++ b/reactos/dll/win32/oleaut32/usrmarshal.c @@ -333,11 +333,12 @@ static unsigned char *interface_variant_unmarshal(ULONG *pFlags, unsigned char * ptr = *(DWORD*)Buffer; Buffer += sizeof(DWORD); + /* Clear any existing interface which WdtpInterfacePointer_UserUnmarshal() + would try to release. This has been done already with a VariantClear(). */ + *ppunk = NULL; + if(!ptr) - { - *ppunk = NULL; return Buffer; - } return WdtpInterfacePointer_UserUnmarshal(pFlags, Buffer, ppunk, riid); } diff --git a/reactos/dll/win32/oleaut32/variant.c b/reactos/dll/win32/oleaut32/variant.c index 8a03dc31e35..ae086fe9035 100644 --- a/reactos/dll/win32/oleaut32/variant.c +++ b/reactos/dll/win32/oleaut32/variant.c @@ -3590,7 +3590,7 @@ HRESULT WINAPI VarDiv(LPVARIANT left, LPVARIANT right, LPVARIANT result) } /* Determine return type */ - if (!(rightvt == VT_EMPTY)) + if (rightvt != VT_EMPTY) { if (leftvt == VT_NULL || rightvt == VT_NULL) { @@ -3623,7 +3623,7 @@ HRESULT WINAPI VarDiv(LPVARIANT left, LPVARIANT right, LPVARIANT result) else if (leftvt == VT_R4 || rightvt == VT_R4) resvt = VT_R4; } - else if (leftvt == VT_NULL && rightvt == VT_EMPTY) + else if (leftvt == VT_NULL) { V_VT(result) = VT_NULL; hres = S_OK; diff --git a/reactos/dll/win32/oleaut32/vartype.c b/reactos/dll/win32/oleaut32/vartype.c index 7ef25e2add0..9417a40b314 100644 --- a/reactos/dll/win32/oleaut32/vartype.c +++ b/reactos/dll/win32/oleaut32/vartype.c @@ -2938,28 +2938,28 @@ HRESULT WINAPI VarR4FromUI4(ULONG ulIn, float *pFltOut) HRESULT WINAPI VarR4FromDec(DECIMAL* pDecIn, float *pFltOut) { BYTE scale = DEC_SCALE(pDecIn); - int divisor = 1; + double divisor = 1.0; double highPart; if (scale > DEC_MAX_SCALE || DEC_SIGN(pDecIn) & ~DECIMAL_NEG) return E_INVALIDARG; while (scale--) - divisor *= 10; + divisor *= 10.0; if (DEC_SIGN(pDecIn)) divisor = -divisor; if (DEC_HI32(pDecIn)) { - highPart = (double)DEC_HI32(pDecIn) / (double)divisor; + highPart = (double)DEC_HI32(pDecIn) / divisor; highPart *= 4294967296.0F; highPart *= 4294967296.0F; } else highPart = 0.0; - *pFltOut = (double)DEC_LO64(pDecIn) / (double)divisor + highPart; + *pFltOut = (double)DEC_LO64(pDecIn) / divisor + highPart; return S_OK; } diff --git a/reactos/media/doc/README.WINE b/reactos/media/doc/README.WINE index 39056ae1837..3093e471978 100644 --- a/reactos/media/doc/README.WINE +++ b/reactos/media/doc/README.WINE @@ -146,7 +146,7 @@ reactos/dll/win32/odbc32 # Synced to WineStaging-1.7.37. Depends on reactos/dll/win32/odbccp32 # Synced to WineStaging-1.7.47 reactos/dll/win32/ole32 # Synced to WineStaging-1.7.55 reactos/dll/win32/oleacc # Synced to WineStaging-1.7.47 -reactos/dll/win32/oleaut32 # Synced to WineStaging-1.7.47 +reactos/dll/win32/oleaut32 # Synced to WineStaging-1.7.55 reactos/dll/win32/olecli32 # Synced to WineStaging-1.7.47 reactos/dll/win32/oledlg # Synced to WineStaging-1.7.47 reactos/dll/win32/olepro32 # Synced to WineStaging-1.7.47 -- 2.17.1