From aeea29430187779d759395c7ace9e03b2e4ccb38 Mon Sep 17 00:00:00 2001 From: Amine Khaldi Date: Tue, 29 Jan 2019 13:15:33 +0100 Subject: [PATCH] [OLE32] Sync with Wine Staging 4.0. CORE-15682 --- dll/win32/ole32/classmoniker.c | 6 +- dll/win32/ole32/clipboard.c | 49 ++++- dll/win32/ole32/compobj.c | 44 ++-- dll/win32/ole32/compobj_private.h | 2 +- dll/win32/ole32/datacache.c | 2 +- dll/win32/ole32/ftmarshal.c | 2 +- dll/win32/ole32/git.c | 16 +- dll/win32/ole32/marshal.c | 336 ++++++++++++++++++++++-------- dll/win32/ole32/moniker.c | 2 +- dll/win32/ole32/ole2.c | 2 +- dll/win32/ole32/ole2impl.c | 99 ++++++++- dll/win32/ole32/rpc.c | 10 +- dll/win32/ole32/stg_prop.c | 4 +- dll/win32/ole32/storage32.c | 17 +- dll/win32/ole32/usrmarshal.c | 4 +- media/doc/README.WINE | 2 +- 16 files changed, 439 insertions(+), 158 deletions(-) diff --git a/dll/win32/ole32/classmoniker.c b/dll/win32/ole32/classmoniker.c index ebad7947c6e..30a24d23e5e 100644 --- a/dll/win32/ole32/classmoniker.c +++ b/dll/win32/ole32/classmoniker.c @@ -536,14 +536,14 @@ static HRESULT WINAPI ClassMoniker_GetDisplayName(IMoniker* iface, *ppszDisplayName = CoTaskMemAlloc(sizeof(wszClsidPrefix) + (CHARS_IN_GUID-2) * sizeof(WCHAR)); - StringFromGUID2(&This->clsid, *ppszDisplayName+sizeof(wszClsidPrefix)/sizeof(WCHAR)-2, CHARS_IN_GUID); + StringFromGUID2(&This->clsid, *ppszDisplayName+ARRAY_SIZE(wszClsidPrefix)-2, CHARS_IN_GUID); /* note: this overwrites the opening curly bracket of the CLSID string generated above */ memcpy(*ppszDisplayName, wszClsidPrefix, sizeof(wszClsidPrefix)-sizeof(WCHAR)); /* note: this overwrites the closing curly bracket of the CLSID string generated above */ - (*ppszDisplayName)[sizeof(wszClsidPrefix)/sizeof(WCHAR)-2+CHARS_IN_GUID-2] = ':'; - (*ppszDisplayName)[sizeof(wszClsidPrefix)/sizeof(WCHAR)-2+CHARS_IN_GUID-1] = '\0'; + (*ppszDisplayName)[ARRAY_SIZE(wszClsidPrefix)-2+CHARS_IN_GUID-2] = ':'; + (*ppszDisplayName)[ARRAY_SIZE(wszClsidPrefix)-2+CHARS_IN_GUID-1] = '\0'; TRACE("string is %s\n", debugstr_w(*ppszDisplayName)); return S_OK; diff --git a/dll/win32/ole32/clipboard.c b/dll/win32/ole32/clipboard.c index 9448f5bc4ab..f3e9a6bc56a 100644 --- a/dll/win32/ole32/clipboard.c +++ b/dll/win32/ole32/clipboard.c @@ -1197,7 +1197,7 @@ static HRESULT get_priv_data(ole_priv_data **data) for(cf = 0; (cf = EnumClipboardFormats(cf)) != 0; count++) { WCHAR buf[256]; - if (GetClipboardFormatNameW(cf, buf, sizeof(buf) / sizeof(WCHAR))) + if (GetClipboardFormatNameW(cf, buf, ARRAY_SIZE(buf))) TRACE("cf %04x %s\n", cf, debugstr_w(buf)); else TRACE("cf %04x\n", cf); @@ -1296,6 +1296,14 @@ static HRESULT get_stgmed_for_storage(HGLOBAL h, STGMEDIUM *med) return hr; } + hr = StgIsStorageILockBytes(lbs); + if(hr!=S_OK) + { + ILockBytes_Release(lbs); + GlobalFree(dst); + return SUCCEEDED(hr) ? E_FAIL : hr; + } + hr = StgOpenStorageOnILockBytes(lbs, NULL, STGM_SHARE_EXCLUSIVE | STGM_READWRITE, NULL, 0, &med->u.pstg); ILockBytes_Release(lbs); if(FAILED(hr)) @@ -1402,12 +1410,19 @@ static HRESULT WINAPI snapshot_GetData(IDataObject *iface, FORMATETC *fmt, if(This->data) { hr = IDataObject_GetData(This->data, fmt, med); - CloseClipboard(); - return hr; + if(SUCCEEDED(hr)) + { + CloseClipboard(); + return hr; + } + } + if(fmt->lindex != -1) + { + hr = DV_E_FORMATETC; + goto end; } - h = GetClipboardData(fmt->cfFormat); - if(!h) + if(!IsClipboardFormatAvailable(fmt->cfFormat)) { hr = DV_E_FORMATETC; goto end; @@ -1425,17 +1440,31 @@ static HRESULT WINAPI snapshot_GetData(IDataObject *iface, FORMATETC *fmt, goto end; } mask = fmt->tymed & entry->fmtetc.tymed; - if(!mask) mask = fmt->tymed & (TYMED_ISTREAM | TYMED_HGLOBAL); + if(!mask && (entry->fmtetc.tymed & (TYMED_ISTREAM | TYMED_HGLOBAL | TYMED_ISTORAGE))) + mask = fmt->tymed & (TYMED_ISTREAM | TYMED_HGLOBAL | TYMED_ISTORAGE); } else /* non-Ole format */ - mask = fmt->tymed & TYMED_HGLOBAL; + mask = fmt->tymed & get_tymed_from_nonole_cf(fmt->cfFormat); - if(mask & TYMED_ISTORAGE) - hr = get_stgmed_for_storage(h, med); - else if(mask & TYMED_HGLOBAL) + if(!mask) + { + hr = DV_E_TYMED; + goto end; + } + + h = GetClipboardData(fmt->cfFormat); + if(!h) + { + hr = DV_E_FORMATETC; + goto end; + } + + if(mask & TYMED_HGLOBAL) hr = get_stgmed_for_global(h, med); else if(mask & TYMED_ISTREAM) hr = get_stgmed_for_stream(h, med); + else if(mask & TYMED_ISTORAGE) + hr = get_stgmed_for_storage(h, med); else if(mask & TYMED_ENHMF) hr = get_stgmed_for_emf((HENHMETAFILE)h, med); else if(mask & TYMED_GDI) diff --git a/dll/win32/ole32/compobj.c b/dll/win32/ole32/compobj.c index 2f4a69aa73a..eae39335fbb 100644 --- a/dll/win32/ole32/compobj.c +++ b/dll/win32/ole32/compobj.c @@ -60,6 +60,7 @@ #include "ctxtcall.h" #include "dde.h" #include "servprov.h" + #ifndef __REACTOS__ #include "initguid.h" #endif @@ -71,9 +72,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(ole); -#undef ARRAYSIZE -#define ARRAYSIZE(array) (sizeof(array)/sizeof((array)[0])) - /**************************************************************************** * This section defines variables internal to the COM module. */ @@ -485,6 +483,8 @@ struct apartment_loaded_dll static const WCHAR wszAptWinClass[] = {'O','l','e','M','a','i','n','T','h','r','e','a','d','W','n','d','C','l','a','s','s',0}; +static ATOM apt_win_class; + /***************************************************************************** * This section contains OpenDllList implementation */ @@ -1412,12 +1412,8 @@ static HRESULT apartment_getclassobject(struct apartment *apt, LPCWSTR dllpath, return hr; } -/*********************************************************************** - * COM_RegReadPath [internal] - * - * Reads a registry value and expands it when necessary - */ -static DWORD COM_RegReadPath(const struct class_reg_data *regdata, WCHAR *dst, DWORD dstlen) +/* Returns expanded dll path from the registry or activation context. */ +static BOOL get_object_dll_path(const struct class_reg_data *regdata, WCHAR *dst, DWORD dstlen) { DWORD ret; @@ -1444,19 +1440,20 @@ static DWORD COM_RegReadPath(const struct class_reg_data *regdata, WCHAR *dst, D lstrcpynW(dst, src, dstlen); } } - return ret; + return !ret; } else { + static const WCHAR dllW[] = {'.','d','l','l',0}; ULONG_PTR cookie; WCHAR *nameW; *dst = 0; nameW = (WCHAR*)((BYTE*)regdata->u.actctx.section + regdata->u.actctx.data->name_offset); ActivateActCtx(regdata->u.actctx.hactctx, &cookie); - ret = SearchPathW(NULL, nameW, NULL, dstlen, dst, NULL); + ret = SearchPathW(NULL, nameW, dllW, dstlen, dst, NULL); DeactivateActCtx(0, cookie); - return !*dst; + return *dst != 0; } } @@ -1481,7 +1478,7 @@ static HRESULT apartment_hostobject(struct apartment *apt, TRACE("clsid %s, iid %s\n", debugstr_guid(¶ms->clsid), debugstr_guid(¶ms->iid)); - if (COM_RegReadPath(¶ms->regdata, dllpath, ARRAYSIZE(dllpath)) != ERROR_SUCCESS) + if (!get_object_dll_path(¶ms->regdata, dllpath, ARRAY_SIZE(dllpath))) { /* failure: CLSID is not found in registry */ WARN("class %s not registered inproc\n", debugstr_guid(¶ms->clsid)); @@ -1701,7 +1698,7 @@ static BOOL WINAPI register_class( INIT_ONCE *once, void *param, void **context wclass.lpfnWndProc = apartment_wndproc; wclass.hInstance = hProxyDll; wclass.lpszClassName = wszAptWinClass; - RegisterClassW(&wclass); + apt_win_class = RegisterClassW(&wclass); return TRUE; } @@ -2360,7 +2357,7 @@ INT WINAPI StringFromGUID2(REFGUID id, LPOLESTR str, INT cmax) HRESULT COM_OpenKeyForCLSID(REFCLSID clsid, LPCWSTR keyname, REGSAM access, HKEY *subkey) { static const WCHAR wszCLSIDSlash[] = {'C','L','S','I','D','\\',0}; - WCHAR path[CHARS_IN_GUID + ARRAYSIZE(wszCLSIDSlash) - 1]; + WCHAR path[CHARS_IN_GUID + ARRAY_SIZE(wszCLSIDSlash) - 1]; LONG res; HKEY key; @@ -2395,7 +2392,7 @@ HRESULT COM_OpenKeyForAppIdFromCLSID(REFCLSID clsid, REGSAM access, HKEY *subkey static const WCHAR szAppIdKey[] = { 'A','p','p','I','d','\\',0 }; DWORD res; WCHAR buf[CHARS_IN_GUID]; - WCHAR keyname[ARRAYSIZE(szAppIdKey) + CHARS_IN_GUID]; + WCHAR keyname[ARRAY_SIZE(szAppIdKey) + CHARS_IN_GUID]; DWORD size; HKEY hkey; DWORD type; @@ -2603,7 +2600,7 @@ HRESULT WINAPI CoGetPSClsid(REFIID riid, CLSID *pclsid) { static const WCHAR wszInterface[] = {'I','n','t','e','r','f','a','c','e','\\',0}; static const WCHAR wszPSC[] = {'\\','P','r','o','x','y','S','t','u','b','C','l','s','i','d','3','2',0}; - WCHAR path[ARRAYSIZE(wszInterface) - 1 + CHARS_IN_GUID - 1 + ARRAYSIZE(wszPSC)]; + WCHAR path[ARRAY_SIZE(wszInterface) - 1 + CHARS_IN_GUID - 1 + ARRAY_SIZE(wszPSC)]; APARTMENT *apt; struct registered_psclsid *registered_psclsid; ACTCTX_SECTION_KEYED_DATA data; @@ -2646,8 +2643,8 @@ HRESULT WINAPI CoGetPSClsid(REFIID riid, CLSID *pclsid) /* Interface\\{string form of riid}\\ProxyStubClsid32 */ strcpyW(path, wszInterface); - StringFromGUID2(riid, path + ARRAYSIZE(wszInterface) - 1, CHARS_IN_GUID); - strcpyW(path + ARRAYSIZE(wszInterface) - 1 + CHARS_IN_GUID - 1, wszPSC); + StringFromGUID2(riid, path + ARRAY_SIZE(wszInterface) - 1, CHARS_IN_GUID); + strcpyW(path + ARRAY_SIZE(wszInterface) - 1 + CHARS_IN_GUID - 1, wszPSC); hr = get_ps_clsid_from_registry(path, 0, pclsid); if (FAILED(hr) && (opposite == KEY_WOW64_32KEY || @@ -2975,7 +2972,7 @@ static HRESULT get_inproc_class_object(APARTMENT *apt, const struct class_reg_da else apartment_threaded = !apt->multi_threaded; - if (COM_RegReadPath(regdata, dllpath, ARRAYSIZE(dllpath)) != ERROR_SUCCESS) + if (!get_object_dll_path(regdata, dllpath, ARRAY_SIZE(dllpath))) { /* failure: CLSID is not found in registry */ WARN("class %s not registered inproc\n", debugstr_guid(rclsid)); @@ -3833,7 +3830,7 @@ HRESULT WINAPI CoTreatAsClass(REFCLSID clsidOld, REFCLSID clsidNew) if(IsEqualGUID(clsidNew, &CLSID_NULL)){ RegDeleteKeyW(hkey, wszTreatAs); }else{ - if(!StringFromGUID2(clsidNew, szClsidNew, ARRAYSIZE(szClsidNew))){ + if(!StringFromGUID2(clsidNew, szClsidNew, ARRAY_SIZE(szClsidNew))){ WARN("StringFromGUID2 failed\n"); res = E_FAIL; goto done; @@ -5091,7 +5088,7 @@ HRESULT Handler_DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) regdata.u.hkey = hkey; regdata.hkey = TRUE; - if (COM_RegReadPath(®data, dllpath, ARRAYSIZE(dllpath)) == ERROR_SUCCESS) + if (get_object_dll_path(®data, dllpath, ARRAY_SIZE(dllpath))) { static const WCHAR wszOle32[] = {'o','l','e','3','2','.','d','l','l',0}; if (!strcmpiW(dllpath, wszOle32)) @@ -5276,7 +5273,8 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID reserved) case DLL_PROCESS_DETACH: if (reserved) break; release_std_git(); - UnregisterClassW( wszAptWinClass, hProxyDll ); + if(apt_win_class) + UnregisterClassW( (const WCHAR*)MAKEINTATOM(apt_win_class), hProxyDll ); RPC_UnregisterAllChannelHooks(); COMPOBJ_DllList_Free(); DeleteCriticalSection(&csRegisteredClassList); diff --git a/dll/win32/ole32/compobj_private.h b/dll/win32/ole32/compobj_private.h index 212d3283171..1e564a3de11 100644 --- a/dll/win32/ole32/compobj_private.h +++ b/dll/win32/ole32/compobj_private.h @@ -210,7 +210,7 @@ struct dispatch_params; void RPC_StartRemoting(struct apartment *apt) DECLSPEC_HIDDEN; HRESULT RPC_CreateClientChannel(const OXID *oxid, const IPID *ipid, - const OXID_INFO *oxid_info, + const OXID_INFO *oxid_info, const IID *iid, DWORD dest_context, void *dest_context_data, IRpcChannelBuffer **chan, APARTMENT *apt) DECLSPEC_HIDDEN; HRESULT RPC_CreateServerChannel(DWORD dest_context, void *dest_context_data, IRpcChannelBuffer **chan) DECLSPEC_HIDDEN; diff --git a/dll/win32/ole32/datacache.c b/dll/win32/ole32/datacache.c index b72b8ff2efe..3eff56908d5 100644 --- a/dll/win32/ole32/datacache.c +++ b/dll/win32/ole32/datacache.c @@ -2667,7 +2667,7 @@ static HRESULT WINAPI DataCache_UpdateCache( IOleCache2 *iface, IDataObject *dat } else { - for (i = 0; i < sizeof(view_list) / sizeof(view_list[0]); i++) + for (i = 0; i < ARRAY_SIZE(view_list); i++) { fmt.cfFormat = view_list[i]; fmt.tymed = tymed_from_cf( fmt.cfFormat ); diff --git a/dll/win32/ole32/ftmarshal.c b/dll/win32/ole32/ftmarshal.c index 3eb7f877aa5..c36f5f61697 100644 --- a/dll/win32/ole32/ftmarshal.c +++ b/dll/win32/ole32/ftmarshal.c @@ -144,7 +144,7 @@ FTMarshalImpl_GetUnmarshalClass (LPMARSHAL iface, REFIID riid, void *pv, DWORD d if (dwDestContext == MSHCTX_INPROC || dwDestContext == MSHCTX_CROSSCTX) *pCid = CLSID_InProcFreeMarshaler; else - *pCid = CLSID_DfMarshal; + *pCid = CLSID_StdMarshal; return S_OK; } diff --git a/dll/win32/ole32/git.c b/dll/win32/ole32/git.c index f7a04601543..8683f3592ac 100644 --- a/dll/win32/ole32/git.c +++ b/dll/win32/ole32/git.c @@ -122,9 +122,14 @@ StdGlobalInterfaceTable_QueryInterface(IGlobalInterfaceTable* iface, /* Do we implement that interface? */ if (IsEqualIID(&IID_IUnknown, riid) || IsEqualIID(&IID_IGlobalInterfaceTable, riid)) + { *ppvObject = iface; + } else + { + FIXME("(%s), not supported.\n", debugstr_guid(riid)); return E_NOINTERFACE; + } /* Now inc the refcount */ IGlobalInterfaceTable_AddRef(iface); @@ -314,13 +319,10 @@ static HRESULT WINAPI GITCF_CreateInstance(LPCLASSFACTORY iface, LPUNKNOWN pUnk, REFIID riid, LPVOID *ppv) { - if (IsEqualIID(riid,&IID_IGlobalInterfaceTable)) { - IGlobalInterfaceTable *git = get_std_git(); - return IGlobalInterfaceTable_QueryInterface(git, riid, ppv); - } - - FIXME("(%s), not supported.\n",debugstr_guid(riid)); - return E_NOINTERFACE; + IGlobalInterfaceTable *git = get_std_git(); + HRESULT hr = IGlobalInterfaceTable_QueryInterface(git, riid, ppv); + IGlobalInterfaceTable_Release(git); + return hr; } static HRESULT WINAPI GITCF_LockServer(LPCLASSFACTORY iface, BOOL fLock) diff --git a/dll/win32/ole32/marshal.c b/dll/win32/ole32/marshal.c index 7c0f5413591..b12082cc9fe 100644 --- a/dll/win32/ole32/marshal.c +++ b/dll/win32/ole32/marshal.c @@ -40,8 +40,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(ole); -extern const CLSID CLSID_DfMarshal; - /* number of refs given out for normal marshaling */ #define NORMALEXTREFS 5 @@ -362,12 +360,7 @@ static const IMultiQIVtbl ClientIdentity_Vtbl = ClientIdentity_QueryMultipleInterfaces }; -/* FIXME: remove these */ -static HRESULT WINAPI StdMarshalImpl_GetUnmarshalClass(LPMARSHAL iface, REFIID riid, void* pv, DWORD dwDestContext, void* pvDestContext, DWORD mshlflags, CLSID* pCid); -static HRESULT WINAPI StdMarshalImpl_GetMarshalSizeMax(LPMARSHAL iface, REFIID riid, void* pv, DWORD dwDestContext, void* pvDestContext, DWORD mshlflags, DWORD* pSize); -static HRESULT WINAPI StdMarshalImpl_UnmarshalInterface(LPMARSHAL iface, IStream *pStm, REFIID riid, void **ppv); -static HRESULT WINAPI StdMarshalImpl_ReleaseMarshalData(LPMARSHAL iface, IStream *pStm); -static HRESULT WINAPI StdMarshalImpl_DisconnectObject(LPMARSHAL iface, DWORD dwReserved); +static HRESULT StdMarshalImpl_Construct(REFIID, DWORD, void*, void**); static HRESULT WINAPI Proxy_QueryInterface(IMarshal *iface, REFIID riid, void **ppvObject) { @@ -387,6 +380,33 @@ static ULONG WINAPI Proxy_Release(IMarshal *iface) return IMultiQI_Release(&This->IMultiQI_iface); } +static HRESULT WINAPI Proxy_GetUnmarshalClass( + IMarshal *iface, REFIID riid, void* pv, DWORD dwDestContext, + void* pvDestContext, DWORD mshlflags, CLSID* pCid) +{ + *pCid = CLSID_StdMarshal; + return S_OK; +} + +static HRESULT WINAPI Proxy_GetMarshalSizeMax( + IMarshal *iface, REFIID riid, void* pv, DWORD dwDestContext, + void* pvDestContext, DWORD mshlflags, DWORD* pSize) +{ + *pSize = FIELD_OFFSET(OBJREF, u_objref.u_standard.saResAddr.aStringArray); + return S_OK; +} + +static void fill_std_objref(OBJREF *objref, const GUID *iid, STDOBJREF *std) +{ + objref->signature = OBJREF_SIGNATURE; + objref->flags = OBJREF_STANDARD; + objref->iid = *iid; + if(std) + objref->u_objref.u_standard.std = *std; + memset(&objref->u_objref.u_standard.saResAddr, 0, + sizeof(objref->u_objref.u_standard.saResAddr)); +} + static HRESULT WINAPI Proxy_MarshalInterface( LPMARSHAL iface, IStream *pStm, REFIID riid, void* pv, DWORD dwDestContext, void* pvDestContext, DWORD mshlflags) @@ -450,12 +470,16 @@ static HRESULT WINAPI Proxy_MarshalInterface( if (SUCCEEDED(hr)) { + OBJREF objref; + TRACE("writing stdobjref: flags = %04x cPublicRefs = %d oxid = %s oid = %s ipid = %s\n", stdobjref.flags, stdobjref.cPublicRefs, wine_dbgstr_longlong(stdobjref.oxid), wine_dbgstr_longlong(stdobjref.oid), debugstr_guid(&stdobjref.ipid)); - hr = IStream_Write(pStm, &stdobjref, sizeof(stdobjref), NULL); + fill_std_objref(&objref, riid, &stdobjref); + hr = IStream_Write(pStm, &objref, FIELD_OFFSET(OBJREF, + u_objref.u_standard.saResAddr.aStringArray), NULL); } } else @@ -481,7 +505,11 @@ static HRESULT WINAPI Proxy_MarshalInterface( 1, &iid, &qiresults); if (SUCCEEDED(hr)) { - hr = IStream_Write(pStm, &qiresults->std, sizeof(qiresults->std), NULL); + OBJREF objref; + + fill_std_objref(&objref, riid, &qiresults->std); + hr = IStream_Write(pStm, &objref, FIELD_OFFSET(OBJREF, + u_objref.u_standard.saResAddr.aStringArray), NULL); if (FAILED(hr)) { REMINTERFACEREF rif; @@ -501,17 +529,72 @@ static HRESULT WINAPI Proxy_MarshalInterface( return hr; } +static HRESULT WINAPI Proxy_UnmarshalInterface( + IMarshal *iface, IStream *pStm, REFIID riid, void **ppv) +{ + struct proxy_manager *This = impl_from_IMarshal( iface ); + IMarshal *marshal; + HRESULT hr; + + TRACE("(%p, %p, %s, %p)\n", This, pStm, wine_dbgstr_guid(riid), ppv); + + hr = StdMarshalImpl_Construct(&IID_IMarshal, This->dest_context, + This->dest_context_data, (void**)&marshal); + if(FAILED(hr)) + return hr; + + hr = IMarshal_UnmarshalInterface(marshal, pStm, riid, ppv); + IMarshal_Release(marshal); + return hr; +} + +static HRESULT WINAPI Proxy_ReleaseMarshalData(IMarshal *iface, IStream *pStm) +{ + struct proxy_manager *This = impl_from_IMarshal( iface ); + IMarshal *marshal; + HRESULT hr; + + TRACE("(%p, %p)\n", This, pStm); + + hr = StdMarshalImpl_Construct(&IID_IMarshal, This->dest_context, + This->dest_context_data, (void**)&marshal); + if(FAILED(hr)) + return hr; + + hr = IMarshal_ReleaseMarshalData(marshal, pStm); + IMarshal_Release(marshal); + return hr; +} + +static HRESULT WINAPI Proxy_DisconnectObject(IMarshal *iface, DWORD dwReserved) +{ + struct proxy_manager *This = impl_from_IMarshal( iface ); + IMarshal *marshal; + HRESULT hr; + + TRACE("(%p, %x)\n", This, dwReserved); + + hr = StdMarshalImpl_Construct(&IID_IMarshal, This->dest_context, + This->dest_context_data, (void**)&marshal); + if(FAILED(hr)) + return hr; + + hr = IMarshal_DisconnectObject(marshal, dwReserved); + IMarshal_Release(marshal); + return hr; +} + static const IMarshalVtbl ProxyMarshal_Vtbl = { Proxy_QueryInterface, Proxy_AddRef, Proxy_Release, - StdMarshalImpl_GetUnmarshalClass, - StdMarshalImpl_GetMarshalSizeMax, + Proxy_GetUnmarshalClass, + Proxy_GetMarshalSizeMax, Proxy_MarshalInterface, - StdMarshalImpl_UnmarshalInterface, - StdMarshalImpl_ReleaseMarshalData, - StdMarshalImpl_DisconnectObject + Proxy_UnmarshalInterface, + Proxy_ReleaseMarshalData, + Proxy_DisconnectObject }; static HRESULT WINAPI ProxyCliSec_QueryInterface(IClientSecurity *iface, REFIID riid, void **ppvObject) @@ -1204,7 +1287,7 @@ StdMarshalImpl_GetUnmarshalClass( IMarshal *iface, REFIID riid, void* pv, DWORD dwDestContext, void* pvDestContext, DWORD mshlflags, CLSID* pCid) { - *pCid = CLSID_DfMarshal; + *pCid = CLSID_StdMarshal; return S_OK; } @@ -1213,7 +1296,7 @@ StdMarshalImpl_GetMarshalSizeMax( IMarshal *iface, REFIID riid, void* pv, DWORD dwDestContext, void* pvDestContext, DWORD mshlflags, DWORD* pSize) { - *pSize = sizeof(STDOBJREF); + *pSize = FIELD_OFFSET(OBJREF, u_objref.u_standard.saResAddr.aStringArray); return S_OK; } @@ -1222,10 +1305,10 @@ StdMarshalImpl_MarshalInterface( IMarshal *iface, IStream *pStm,REFIID riid, void* pv, DWORD dest_context, void* dest_context_data, DWORD mshlflags) { - STDOBJREF stdobjref; ULONG res; HRESULT hres; APARTMENT *apt; + OBJREF objref; TRACE("(...,%s,...)\n", debugstr_guid(riid)); @@ -1238,7 +1321,9 @@ StdMarshalImpl_MarshalInterface( /* make sure this apartment can be reached from other threads / processes */ RPC_StartRemoting(apt); - hres = marshal_object(apt, &stdobjref, riid, pv, dest_context, dest_context_data, mshlflags); + fill_std_objref(&objref, riid, NULL); + hres = marshal_object(apt, &objref.u_objref.u_standard.std, riid, + pv, dest_context, dest_context_data, mshlflags); apartment_release(apt); if (hres != S_OK) { @@ -1246,7 +1331,8 @@ StdMarshalImpl_MarshalInterface( return hres; } - return IStream_Write(pStm, &stdobjref, sizeof(stdobjref), &res); + return IStream_Write(pStm, &objref, + FIELD_OFFSET(OBJREF, u_objref.u_standard.saResAddr.aStringArray), &res); } /* helper for StdMarshalImpl_UnmarshalInterface - does the unmarshaling with @@ -1290,7 +1376,7 @@ static HRESULT unmarshal_object(const STDOBJREF *stdobjref, APARTMENT *apt, { IRpcChannelBuffer *chanbuf; hr = RPC_CreateClientChannel(&stdobjref->oxid, &stdobjref->ipid, - &proxy_manager->oxid_info, + &proxy_manager->oxid_info, riid, proxy_manager->dest_context, proxy_manager->dest_context_data, &chanbuf, apt); @@ -1321,12 +1407,11 @@ static HRESULT unmarshal_object(const STDOBJREF *stdobjref, APARTMENT *apt, return hr; } -static HRESULT WINAPI -StdMarshalImpl_UnmarshalInterface(IMarshal *iface, IStream *pStm, REFIID riid, void **ppv) +static HRESULT std_unmarshal_interface(MSHCTX dest_context, void *dest_context_data, + IStream *pStm, REFIID riid, void **ppv) { - StdMarshalImpl *This = impl_from_StdMarshal(iface); struct stub_manager *stubmgr = NULL; - STDOBJREF stdobjref; + struct OR_STANDARD obj; ULONG res; HRESULT hres; APARTMENT *apt; @@ -1343,7 +1428,7 @@ StdMarshalImpl_UnmarshalInterface(IMarshal *iface, IStream *pStm, REFIID riid, v } /* read STDOBJREF from wire */ - hres = IStream_Read(pStm, &stdobjref, sizeof(stdobjref), &res); + hres = IStream_Read(pStm, &obj, FIELD_OFFSET(struct OR_STANDARD, saResAddr.aStringArray), &res); if (hres != S_OK) { apartment_release(apt); @@ -1357,8 +1442,14 @@ StdMarshalImpl_UnmarshalInterface(IMarshal *iface, IStream *pStm, REFIID riid, v return hres; } + if (obj.saResAddr.wNumEntries) + { + ERR("unsupported size of DUALSTRINGARRAY\n"); + return E_NOTIMPL; + } + /* check if we're marshalling back to ourselves */ - if ((oxid == stdobjref.oxid) && (stubmgr = get_stub_manager(apt, stdobjref.oid))) + if ((oxid == obj.std.oxid) && (stubmgr = get_stub_manager(apt, obj.std.oid))) { TRACE("Unmarshalling object marshalled in same apartment for iid %s, " "returning original object %p\n", debugstr_guid(riid), stubmgr->object); @@ -1366,8 +1457,8 @@ StdMarshalImpl_UnmarshalInterface(IMarshal *iface, IStream *pStm, REFIID riid, v hres = IUnknown_QueryInterface(stubmgr->object, riid, ppv); /* unref the ifstub. FIXME: only do this on success? */ - if (!stub_manager_is_table_marshaled(stubmgr, &stdobjref.ipid)) - stub_manager_ext_release(stubmgr, stdobjref.cPublicRefs, stdobjref.flags & SORFP_TABLEWEAK, FALSE); + if (!stub_manager_is_table_marshaled(stubmgr, &obj.std.ipid)) + stub_manager_ext_release(stubmgr, obj.std.cPublicRefs, obj.std.flags & SORFP_TABLEWEAK, FALSE); stub_manager_int_release(stubmgr); apartment_release(apt); @@ -1379,28 +1470,28 @@ StdMarshalImpl_UnmarshalInterface(IMarshal *iface, IStream *pStm, REFIID riid, v * ignore table marshaling and normal marshaling rules regarding number of * unmarshals, etc, but if you abuse these rules then your proxy could end * up returning RPC_E_DISCONNECTED. */ - if ((stub_apt = apartment_findfromoxid(stdobjref.oxid, TRUE))) + if ((stub_apt = apartment_findfromoxid(obj.std.oxid, TRUE))) { - if ((stubmgr = get_stub_manager(stub_apt, stdobjref.oid))) + if ((stubmgr = get_stub_manager(stub_apt, obj.std.oid))) { - if (!stub_manager_notify_unmarshal(stubmgr, &stdobjref.ipid)) + if (!stub_manager_notify_unmarshal(stubmgr, &obj.std.ipid)) hres = CO_E_OBJNOTCONNECTED; } else { WARN("Couldn't find object for OXID %s, OID %s, assuming disconnected\n", - wine_dbgstr_longlong(stdobjref.oxid), - wine_dbgstr_longlong(stdobjref.oid)); + wine_dbgstr_longlong(obj.std.oxid), + wine_dbgstr_longlong(obj.std.oid)); hres = CO_E_OBJNOTCONNECTED; } } else TRACE("Treating unmarshal from OXID %s as inter-process\n", - wine_dbgstr_longlong(stdobjref.oxid)); + wine_dbgstr_longlong(obj.std.oxid)); if (hres == S_OK) - hres = unmarshal_object(&stdobjref, apt, This->dest_context, - This->dest_context_data, riid, + hres = unmarshal_object(&obj.std, apt, dest_context, + dest_context_data, riid, stubmgr ? &stubmgr->oxid_info : NULL, ppv); if (stubmgr) stub_manager_int_release(stubmgr); @@ -1414,40 +1505,74 @@ StdMarshalImpl_UnmarshalInterface(IMarshal *iface, IStream *pStm, REFIID riid, v } static HRESULT WINAPI -StdMarshalImpl_ReleaseMarshalData(IMarshal *iface, IStream *pStm) +StdMarshalImpl_UnmarshalInterface(IMarshal *iface, IStream *pStm, REFIID riid, void **ppv) { - STDOBJREF stdobjref; + StdMarshalImpl *This = impl_from_StdMarshal(iface); + OBJREF objref; + HRESULT hr; + ULONG res; + + hr = IStream_Read(pStm, &objref, FIELD_OFFSET(OBJREF, u_objref), &res); + if (hr != S_OK || (res != FIELD_OFFSET(OBJREF, u_objref))) + { + ERR("Failed to read common OBJREF header, 0x%08x\n", hr); + return STG_E_READFAULT; + } + + if (objref.signature != OBJREF_SIGNATURE) + { + ERR("Bad OBJREF signature 0x%08x\n", objref.signature); + return RPC_E_INVALID_OBJREF; + } + + if (!(objref.flags & OBJREF_STANDARD)) + { + FIXME("unsupported objref.flags = %x\n", objref.flags); + return E_NOTIMPL; + } + + return std_unmarshal_interface(This->dest_context, + This->dest_context_data, pStm, riid, ppv); +} + +static HRESULT std_release_marshal_data(IStream *pStm) +{ + struct OR_STANDARD obj; ULONG res; HRESULT hres; struct stub_manager *stubmgr; APARTMENT *apt; - TRACE("iface=%p, pStm=%p\n", iface, pStm); - - hres = IStream_Read(pStm, &stdobjref, sizeof(stdobjref), &res); + hres = IStream_Read(pStm, &obj, FIELD_OFFSET(struct OR_STANDARD, saResAddr.aStringArray), &res); if (hres != S_OK) return STG_E_READFAULT; - TRACE("oxid = %s, oid = %s, ipid = %s\n", - wine_dbgstr_longlong(stdobjref.oxid), - wine_dbgstr_longlong(stdobjref.oid), - wine_dbgstr_guid(&stdobjref.ipid)); + if (obj.saResAddr.wNumEntries) + { + ERR("unsupported size of DUALSTRINGARRAY\n"); + return E_NOTIMPL; + } - if (!(apt = apartment_findfromoxid(stdobjref.oxid, TRUE))) + TRACE("oxid = %s, oid = %s, ipid = %s\n", + wine_dbgstr_longlong(obj.std.oxid), + wine_dbgstr_longlong(obj.std.oid), + wine_dbgstr_guid(&obj.std.ipid)); + + if (!(apt = apartment_findfromoxid(obj.std.oxid, TRUE))) { WARN("Could not map OXID %s to apartment object\n", - wine_dbgstr_longlong(stdobjref.oxid)); + wine_dbgstr_longlong(obj.std.oxid)); return RPC_E_INVALID_OBJREF; } - if (!(stubmgr = get_stub_manager(apt, stdobjref.oid))) + if (!(stubmgr = get_stub_manager(apt, obj.std.oid))) { apartment_release(apt); ERR("could not map object ID to stub manager, oxid=%s, oid=%s\n", - wine_dbgstr_longlong(stdobjref.oxid), wine_dbgstr_longlong(stdobjref.oid)); + wine_dbgstr_longlong(obj.std.oxid), wine_dbgstr_longlong(obj.std.oid)); return RPC_E_INVALID_OBJREF; } - stub_manager_release_marshal_data(stubmgr, stdobjref.cPublicRefs, &stdobjref.ipid, stdobjref.flags & SORFP_TABLEWEAK); + stub_manager_release_marshal_data(stubmgr, obj.std.cPublicRefs, &obj.std.ipid, obj.std.flags & SORFP_TABLEWEAK); stub_manager_int_release(stubmgr); apartment_release(apt); @@ -1455,6 +1580,37 @@ StdMarshalImpl_ReleaseMarshalData(IMarshal *iface, IStream *pStm) return S_OK; } +static HRESULT WINAPI +StdMarshalImpl_ReleaseMarshalData(IMarshal *iface, IStream *pStm) +{ + OBJREF objref; + HRESULT hr; + ULONG res; + + TRACE("iface=%p, pStm=%p\n", iface, pStm); + + hr = IStream_Read(pStm, &objref, FIELD_OFFSET(OBJREF, u_objref), &res); + if (hr != S_OK || (res != FIELD_OFFSET(OBJREF, u_objref))) + { + ERR("Failed to read common OBJREF header, 0x%08x\n", hr); + return STG_E_READFAULT; + } + + if (objref.signature != OBJREF_SIGNATURE) + { + ERR("Bad OBJREF signature 0x%08x\n", objref.signature); + return RPC_E_INVALID_OBJREF; + } + + if (!(objref.flags & OBJREF_STANDARD)) + { + FIXME("unsupported objref.flags = %x\n", objref.flags); + return E_NOTIMPL; + } + + return std_release_marshal_data(pStm); +} + static HRESULT WINAPI StdMarshalImpl_DisconnectObject(IMarshal *iface, DWORD dwReserved) { @@ -1588,7 +1744,8 @@ static HRESULT get_unmarshaler_from_stream(IStream *stream, IMarshal **marshal, if (objref.flags & OBJREF_STANDARD) { TRACE("Using standard unmarshaling\n"); - hr = StdMarshalImpl_Construct(&IID_IMarshal, 0, NULL, (LPVOID*)marshal); + *marshal = NULL; + return S_FALSE; } else if (objref.flags & OBJREF_CUSTOM) { @@ -1647,29 +1804,25 @@ HRESULT WINAPI CoGetMarshalSizeMax(ULONG *pulSize, REFIID riid, IUnknown *pUnk, { HRESULT hr; LPMARSHAL pMarshal; - CLSID marshaler_clsid; + BOOL std_marshal = FALSE; - hr = get_marshaler(riid, pUnk, dwDestContext, pvDestContext, mshlFlags, &pMarshal); - if (hr != S_OK) - return hr; + if(!pUnk) + return E_POINTER; - hr = IMarshal_GetUnmarshalClass(pMarshal, riid, pUnk, dwDestContext, - pvDestContext, mshlFlags, &marshaler_clsid); + hr = IUnknown_QueryInterface(pUnk, &IID_IMarshal, (void**)&pMarshal); if (hr != S_OK) { - ERR("IMarshal::GetUnmarshalClass failed, 0x%08x\n", hr); - IMarshal_Release(pMarshal); - return hr; + std_marshal = TRUE; + hr = CoGetStandardMarshal(riid, pUnk, dwDestContext, pvDestContext, + mshlFlags, &pMarshal); } + if (hr != S_OK) + return hr; hr = IMarshal_GetMarshalSizeMax(pMarshal, riid, pUnk, dwDestContext, pvDestContext, mshlFlags, pulSize); - if (IsEqualCLSID(&marshaler_clsid, &CLSID_DfMarshal)) - /* add on the size of the common header */ - *pulSize += FIELD_OFFSET(OBJREF, u_objref); - else - /* custom marshaling: add on the size of the whole OBJREF structure - * like native does */ + if (!std_marshal) + /* add on the size of the whole OBJREF structure like native does */ *pulSize += sizeof(OBJREF); IMarshal_Release(pMarshal); @@ -1727,7 +1880,6 @@ HRESULT WINAPI CoMarshalInterface(IStream *pStream, REFIID riid, IUnknown *pUnk, { HRESULT hr; CLSID marshaler_clsid; - OBJREF objref; LPMARSHAL pMarshal; TRACE("(%p, %s, %p, %x, %p, ", pStream, debugstr_guid(riid), pUnk, @@ -1738,9 +1890,6 @@ HRESULT WINAPI CoMarshalInterface(IStream *pStream, REFIID riid, IUnknown *pUnk, if (!pUnk || !pStream) return E_INVALIDARG; - objref.signature = OBJREF_SIGNATURE; - objref.iid = *riid; - /* get the marshaler for the specified interface */ hr = get_marshaler(riid, pUnk, dwDestContext, pvDestContext, mshlFlags, &pMarshal); if (hr != S_OK) @@ -1758,22 +1907,17 @@ HRESULT WINAPI CoMarshalInterface(IStream *pStream, REFIID riid, IUnknown *pUnk, } /* FIXME: implement handler marshaling too */ - if (IsEqualCLSID(&marshaler_clsid, &CLSID_DfMarshal)) + if (IsEqualCLSID(&marshaler_clsid, &CLSID_StdMarshal)) { TRACE("Using standard marshaling\n"); - objref.flags = OBJREF_STANDARD; - - /* write the common OBJREF header to the stream */ - hr = IStream_Write(pStream, &objref, FIELD_OFFSET(OBJREF, u_objref), NULL); - if (hr != S_OK) - { - ERR("Failed to write OBJREF header to stream, 0x%08x\n", hr); - goto cleanup; - } } else { + OBJREF objref; + TRACE("Using custom marshaling\n"); + objref.signature = OBJREF_SIGNATURE; + objref.iid = *riid; objref.flags = OBJREF_CUSTOM; objref.u_objref.u_custom.clsid = marshaler_clsid; objref.u_objref.u_custom.cbExtension = 0; @@ -1848,13 +1992,20 @@ HRESULT WINAPI CoUnmarshalInterface(IStream *pStream, REFIID riid, LPVOID *ppv) return E_INVALIDARG; hr = get_unmarshaler_from_stream(pStream, &pMarshal, &iid); - if (hr != S_OK) - return hr; - - /* call the helper object to do the actual unmarshaling */ - hr = IMarshal_UnmarshalInterface(pMarshal, pStream, &iid, (LPVOID*)&object); - if (hr != S_OK) - ERR("IMarshal::UnmarshalInterface failed, 0x%08x\n", hr); + if (hr == S_FALSE) + { + hr = std_unmarshal_interface(0, NULL, pStream, &iid, (void**)&object); + if (hr != S_OK) + ERR("StdMarshal UnmarshalInterface failed, 0x%08x\n", hr); + } + else if (hr == S_OK) + { + /* call the helper object to do the actual unmarshaling */ + hr = IMarshal_UnmarshalInterface(pMarshal, pStream, &iid, (LPVOID*)&object); + IMarshal_Release(pMarshal); + if (hr != S_OK) + ERR("IMarshal::UnmarshalInterface failed, 0x%08x\n", hr); + } if (hr == S_OK) { @@ -1874,8 +2025,6 @@ HRESULT WINAPI CoUnmarshalInterface(IStream *pStream, REFIID riid, LPVOID *ppv) } } - IMarshal_Release(pMarshal); - TRACE("completed with hr 0x%x\n", hr); return hr; @@ -1912,6 +2061,13 @@ HRESULT WINAPI CoReleaseMarshalData(IStream *pStream) TRACE("(%p)\n", pStream); hr = get_unmarshaler_from_stream(pStream, &pMarshal, NULL); + if (hr == S_FALSE) + { + hr = std_release_marshal_data(pStream); + if (hr != S_OK) + ERR("StdMarshal ReleaseMarshalData failed with error 0x%08x\n", hr); + return hr; + } if (hr != S_OK) return hr; diff --git a/dll/win32/ole32/moniker.c b/dll/win32/ole32/moniker.c index ffbaa61e50a..c1312d1e1e3 100644 --- a/dll/win32/ole32/moniker.c +++ b/dll/win32/ole32/moniker.c @@ -1152,7 +1152,7 @@ HRESULT WINAPI MkParseDisplayName(LPBC pbc, LPCOLESTR szDisplayName, *pchEaten = 0; *ppmk = NULL; - if (!strncmpiW(szDisplayName, wszClsidColon, sizeof(wszClsidColon)/sizeof(wszClsidColon[0]))) + if (!strncmpiW(szDisplayName, wszClsidColon, ARRAY_SIZE(wszClsidColon))) { hr = ClassMoniker_CreateFromDisplayName(pbc, szDisplayName, &chEaten, &moniker); if (FAILED(hr) && (hr != MK_E_SYNTAX)) diff --git a/dll/win32/ole32/ole2.c b/dll/win32/ole32/ole2.c index c7a9b272cb3..2de9edbb80c 100644 --- a/dll/win32/ole32/ole2.c +++ b/dll/win32/ole32/ole2.c @@ -967,7 +967,7 @@ static HRESULT WINAPI EnumOLEVERB_Next( LPWSTR pwszOLEVERB; LPWSTR pwszMenuFlags; LPWSTR pwszAttribs; - LONG res = RegEnumKeyW(This->hkeyVerb, This->index, wszSubKey, sizeof(wszSubKey)/sizeof(wszSubKey[0])); + LONG res = RegEnumKeyW(This->hkeyVerb, This->index, wszSubKey, ARRAY_SIZE(wszSubKey)); if (res == ERROR_NO_MORE_ITEMS) { hr = S_FALSE; diff --git a/dll/win32/ole32/ole2impl.c b/dll/win32/ole32/ole2impl.c index ccf31fa4f5a..e3820b9ac22 100644 --- a/dll/win32/ole32/ole2impl.c +++ b/dll/win32/ole32/ole2impl.c @@ -135,7 +135,7 @@ static HRESULT get_storage(IDataObject *data, IStorage *stg, UINT *src_cf, BOOL if (other_fmts) { - for (i = 0; i < sizeof(fmt_id)/sizeof(fmt_id[0]); i++) + for (i = 0; i < ARRAY_SIZE(fmt_id); i++) { init_fmtetc(&fmt, fmt_id[i], TYMED_ISTORAGE); hr = IDataObject_QueryGetData(data, &fmt); @@ -232,9 +232,102 @@ HRESULT WINAPI OleCreateStaticFromData(IDataObject *data, REFIID iid, IOleClientSite *client_site, IStorage *stg, void **obj) { - FIXME("%p,%s,%08x,%p,%p,%p,%p: semi-stub\n", + HRESULT hr; + CLSID clsid; + IOleObject * ole_object = NULL; + IOleCache2 *ole_cache = NULL; + IPersistStorage *persist = NULL; + DWORD connection; + STGMEDIUM stgmedium; + LPOLESTR ole_typename; + + TRACE("(%p, %s, 0x%08x, %p, %p, %p, %p)\n", data, debugstr_guid(iid), renderopt, fmt, client_site, stg, obj); - return OleCreateFromData(data, iid, renderopt, fmt, client_site, stg, obj); + + if (!obj || !stg) + return E_INVALIDARG; + + if (renderopt != OLERENDER_FORMAT) + { + FIXME("semi-stub\n"); + return OleCreateFromData(data, iid, renderopt, fmt, client_site, stg, obj); + } + + if (!fmt) + return E_INVALIDARG; + + hr = IDataObject_GetData(data, fmt, &stgmedium); + if (FAILED(hr)) return hr; + + switch (fmt->cfFormat) + { + case CF_BITMAP: + case CF_DIB: + clsid = CLSID_Picture_Dib; + break; + case CF_ENHMETAFILE: + clsid = CLSID_Picture_EnhMetafile; + break; + case CF_METAFILEPICT: + clsid = CLSID_Picture_Metafile; + break; + default: + ReleaseStgMedium(&stgmedium); + return DV_E_CLIPFORMAT; + } + hr = OleCreateDefaultHandler(&clsid, NULL, &IID_IOleObject, (void **)&ole_object); + if (FAILED(hr)) goto end; + + if (client_site) + { + hr = IOleObject_SetClientSite(ole_object, client_site); + if (FAILED(hr)) goto end; + } + + hr = IOleObject_QueryInterface(ole_object, &IID_IOleCache2, (void **)&ole_cache); + if (FAILED(hr)) goto end; + + hr = IOleObject_QueryInterface(ole_object, &IID_IPersistStorage, (void **)&persist); + if (FAILED(hr)) goto end; + + hr = WriteClassStg(stg, &clsid); + if (FAILED(hr)) goto end; + + hr = IPersistStorage_InitNew(persist, stg); + if (FAILED(hr)) goto end; + + hr = IOleCache2_Cache(ole_cache, fmt, ADVF_PRIMEFIRST, &connection); + if (FAILED(hr)) goto end; + + hr = IOleCache2_SetData(ole_cache, fmt, &stgmedium, TRUE); + if (FAILED(hr)) goto end; + stgmedium.tymed = TYMED_NULL; + + hr = IOleObject_GetUserType(ole_object, USERCLASSTYPE_FULL, &ole_typename); + if(FAILED(hr)) + ole_typename = NULL; + hr = WriteFmtUserTypeStg(stg, fmt->cfFormat, ole_typename); + CoTaskMemFree(ole_typename); + if (FAILED(hr)) goto end; + + hr = IPersistStorage_Save(persist, stg, TRUE); + if (FAILED(hr)) goto end; + + hr = IPersistStorage_SaveCompleted(persist, NULL); + if (FAILED(hr)) goto end; + + hr = IOleObject_QueryInterface(ole_object, iid, obj); + +end: + if (stgmedium.tymed == TYMED_NULL) + ReleaseStgMedium(&stgmedium); + if (persist) + IPersistStorage_Release(persist); + if (ole_cache) + IOleCache2_Release(ole_cache); + if (ole_object) + IOleObject_Release(ole_object); + return hr; } /****************************************************************************** diff --git a/dll/win32/ole32/rpc.c b/dll/win32/ole32/rpc.c index a73d23ce683..bd4611d7d5f 100644 --- a/dll/win32/ole32/rpc.c +++ b/dll/win32/ole32/rpc.c @@ -109,6 +109,7 @@ typedef struct OXID oxid; /* apartment in which the channel is valid */ DWORD server_pid; /* id of server process */ HANDLE event; /* cached event handle */ + IID iid; /* IID of the proxy this belongs to */ } ClientRpcChannelBuffer; struct dispatch_params @@ -650,7 +651,7 @@ static HRESULT WINAPI ClientRpcChannelBuffer_GetBuffer(LPRPCCHANNELBUFFER iface, cif->Length = sizeof(RPC_CLIENT_INTERFACE); /* RPC interface ID = COM interface ID */ - cif->InterfaceId.SyntaxGUID = *riid; + cif->InterfaceId.SyntaxGUID = This->iid; /* COM objects always have a version of 0.0 */ cif->InterfaceId.SyntaxVersion.MajorVersion = 0; cif->InterfaceId.SyntaxVersion.MinorVersion = 0; @@ -1096,7 +1097,7 @@ static const IRpcChannelBufferVtbl ServerRpcChannelBufferVtbl = /* returns a channel buffer for proxies */ HRESULT RPC_CreateClientChannel(const OXID *oxid, const IPID *ipid, - const OXID_INFO *oxid_info, + const OXID_INFO *oxid_info, const IID *iid, DWORD dest_context, void *dest_context_data, IRpcChannelBuffer **chan, APARTMENT *apt) { @@ -1155,6 +1156,7 @@ HRESULT RPC_CreateClientChannel(const OXID *oxid, const IPID *ipid, apartment_getoxid(apt, &This->oxid); This->server_pid = oxid_info->dwPid; This->event = NULL; + This->iid = *iid; *chan = &This->super.IRpcChannelBuffer_iface; @@ -1658,7 +1660,7 @@ static HRESULT create_server(REFCLSID rclsid, HANDLE *process) static const WCHAR embedding[] = { ' ', '-','E','m','b','e','d','d','i','n','g',0 }; HKEY key; HRESULT hres; - WCHAR command[MAX_PATH+sizeof(embedding)/sizeof(WCHAR)]; + WCHAR command[MAX_PATH+ARRAY_SIZE(embedding)]; DWORD size = (MAX_PATH+1) * sizeof(WCHAR); STARTUPINFOW sinfo; PROCESS_INFORMATION pinfo; @@ -1799,7 +1801,7 @@ static void get_localserver_pipe_name(WCHAR *pipefn, REFCLSID rclsid) { static const WCHAR wszPipeRef[] = {'\\','\\','.','\\','p','i','p','e','\\',0}; strcpyW(pipefn, wszPipeRef); - StringFromGUID2(rclsid, pipefn + sizeof(wszPipeRef)/sizeof(wszPipeRef[0]) - 1, CHARS_IN_GUID); + StringFromGUID2(rclsid, pipefn + ARRAY_SIZE(wszPipeRef) - 1, CHARS_IN_GUID); } /* FIXME: should call to rpcss instead */ diff --git a/dll/win32/ole32/stg_prop.c b/dll/win32/ole32/stg_prop.c index 1d5e03473d9..4b968d6e9cc 100644 --- a/dll/win32/ole32/stg_prop.c +++ b/dll/win32/ole32/stg_prop.c @@ -1058,11 +1058,13 @@ static HRESULT PropertyStorage_ReadProperty(PROPVARIANT *prop, const BYTE *data, UINT codepage, void* (__thiscall_wrapper *allocate)(void *this, ULONG size), void *allocate_data) { HRESULT hr = S_OK; + DWORD vt; assert(prop); assert(data); - StorageUtl_ReadDWord(data, 0, (DWORD *)&prop->vt); + StorageUtl_ReadDWord(data, 0, &vt); data += sizeof(DWORD); + prop->vt = vt; switch (prop->vt) { case VT_EMPTY: diff --git a/dll/win32/ole32/storage32.c b/dll/win32/ole32/storage32.c index 51f178be8ee..a8bbd407dd7 100644 --- a/dll/win32/ole32/storage32.c +++ b/dll/win32/ole32/storage32.c @@ -5057,7 +5057,7 @@ static HRESULT StorageImpl_LockOne(StorageImpl *This, ULONG start, ULONG end) if (SUCCEEDED(hr)) { - for (j=0; jlocked_bytes)/sizeof(This->locked_bytes[0]); j++) + for (j = 0; j < ARRAY_SIZE(This->locked_bytes); j++) { if (This->locked_bytes[j] == 0) { @@ -5200,10 +5200,10 @@ static void StorageImpl_Destroy(StorageBaseImpl* iface) BlockChainStream_Destroy(This->rootBlockChain); BlockChainStream_Destroy(This->smallBlockDepotChain); - for (i=0; iblockChainCache[i]); - for (i=0; ilocked_bytes)/sizeof(This->locked_bytes[0]); i++) + for (i = 0; i < ARRAY_SIZE(This->locked_bytes); i++) { ULARGE_INTEGER offset, cb; cb.QuadPart = 1; @@ -9369,8 +9369,7 @@ HRESULT WINAPI WriteFmtUserTypeStg( /* get the clipboard format name */ if( cf ) { - n = GetClipboardFormatNameW( cf, szwClipName, - sizeof(szwClipName)/sizeof(szwClipName[0]) ); + n = GetClipboardFormatNameW(cf, szwClipName, ARRAY_SIZE(szwClipName)); szwClipName[n]=0; } @@ -10035,8 +10034,8 @@ HRESULT OLECONVERT_CreateCompObjStream(LPSTORAGE pStorage, LPCSTR strOleTypeName static const WCHAR wstrStreamName[] = {1,'C', 'o', 'm', 'p', 'O', 'b', 'j', 0}; WCHAR bufferW[OLESTREAM_MAX_STR_LEN]; - BYTE pCompObjUnknown1[] = {0x01, 0x00, 0xFE, 0xFF, 0x03, 0x0A, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF}; - BYTE pCompObjUnknown2[] = {0xF4, 0x39, 0xB2, 0x71}; + static const BYTE pCompObjUnknown1[] = {0x01, 0x00, 0xFE, 0xFF, 0x03, 0x0A, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF}; + static const BYTE pCompObjUnknown2[] = {0xF4, 0x39, 0xB2, 0x71}; /* Initialize the CompObj structure */ memset(&IStorageCompObj, 0, sizeof(IStorageCompObj)); @@ -10134,7 +10133,7 @@ static void OLECONVERT_CreateOlePresStream(LPSTORAGE pStorage, DWORD dwExtentX, HRESULT hRes; IStream *pStream; static const WCHAR wstrStreamName[] = {2, 'O', 'l', 'e', 'P', 'r', 'e', 's', '0', '0', '0', 0}; - BYTE pOlePresStreamHeader [] = + static const BYTE pOlePresStreamHeader[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, @@ -10142,7 +10141,7 @@ static void OLECONVERT_CreateOlePresStream(LPSTORAGE pStorage, DWORD dwExtentX, 0x00, 0x00, 0x00, 0x00 }; - BYTE pOlePresStreamHeaderEmpty [] = + static const BYTE pOlePresStreamHeaderEmpty[] = { 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, diff --git a/dll/win32/ole32/usrmarshal.c b/dll/win32/ole32/usrmarshal.c index 3d1284a431c..9f19b66d635 100644 --- a/dll/win32/ole32/usrmarshal.c +++ b/dll/win32/ole32/usrmarshal.c @@ -116,7 +116,7 @@ ULONG __RPC_USER CLIPFORMAT_UserSize(ULONG *pFlags, ULONG size, CLIPFORMAT *pCF) /* urg! this function is badly designed because it won't tell us how * much space is needed without doing a dummy run of storing the * name into a buffer */ - ret = GetClipboardFormatNameW(*pCF, format, sizeof(format)/sizeof(format[0])-1); + ret = GetClipboardFormatNameW(*pCF, format, ARRAY_SIZE(format)-1); if (!ret) RaiseException(DV_E_CLIPFORMAT, 0, 0, NULL); size += (ret + 1) * sizeof(WCHAR); @@ -161,7 +161,7 @@ unsigned char * __RPC_USER CLIPFORMAT_UserMarshal(ULONG *pFlags, unsigned char * *(DWORD *)pBuffer = *pCF; pBuffer += 4; - len = GetClipboardFormatNameW(*pCF, format, sizeof(format)/sizeof(format[0])-1); + len = GetClipboardFormatNameW(*pCF, format, ARRAY_SIZE(format)-1); if (!len) RaiseException(DV_E_CLIPFORMAT, 0, 0, NULL); len += 1; diff --git a/media/doc/README.WINE b/media/doc/README.WINE index 7b4141c99ba..5313ce69e95 100644 --- a/media/doc/README.WINE +++ b/media/doc/README.WINE @@ -139,7 +139,7 @@ reactos/dll/win32/ntdsapi # Synced to WineStaging-3.9 reactos/dll/win32/objsel # Synced to WineStaging-3.3 reactos/dll/win32/odbc32 # Synced to WineStaging-4.0. Depends on port of Linux ODBC. reactos/dll/win32/odbccp32 # Synced to WineStaging-4.0 -reactos/dll/win32/ole32 # Synced to WineStaging-3.9 +reactos/dll/win32/ole32 # Synced to WineStaging-4.0 reactos/dll/win32/oleacc # Synced to WineStaging-3.3 reactos/dll/win32/oleaut32 # Synced to WineStaging-3.3 reactos/dll/win32/olecli32 # Synced to WineStaging-3.3