Author: akhaldi Date: Tue Nov 17 10:30:40 2015 New Revision: 69908
URL: http://svn.reactos.org/svn/reactos?rev=69908&view=rev Log: [OLE32] Sync with Wine Staging 1.7.55. CORE-10536
Modified: trunk/reactos/dll/win32/ole32/compobj.c trunk/reactos/dll/win32/ole32/compobj_private.h trunk/reactos/dll/win32/ole32/datacache.c trunk/reactos/dll/win32/ole32/defaulthandler.c trunk/reactos/dll/win32/ole32/filemoniker.c trunk/reactos/dll/win32/ole32/marshal.c trunk/reactos/dll/win32/ole32/ole2.c trunk/reactos/dll/win32/ole32/ole2impl.c trunk/reactos/dll/win32/ole32/ole2stubs.c trunk/reactos/dll/win32/ole32/ole32.spec trunk/reactos/dll/win32/ole32/ole32_main.c trunk/reactos/dll/win32/ole32/rpc.c trunk/reactos/dll/win32/ole32/storage32.c trunk/reactos/dll/win32/ole32/stubmanager.c trunk/reactos/dll/win32/ole32/usrmarshal.c trunk/reactos/media/doc/README.WINE
Modified: trunk/reactos/dll/win32/ole32/compobj.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/ole32/compobj.c?r... ============================================================================== --- trunk/reactos/dll/win32/ole32/compobj.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/ole32/compobj.c [iso-8859-1] Tue Nov 17 10:30:40 2015 @@ -1003,7 +1003,7 @@ * SEE ALSO * CoRegisterClassObject */ -HRESULT WINAPI CoRevokeClassObject( +HRESULT WINAPI DECLSPEC_HOTPATCH CoRevokeClassObject( DWORD dwRegister) { HRESULT hr = E_INVALIDARG; @@ -1851,7 +1851,7 @@ * SEE ALSO * CoUninitialize */ -HRESULT WINAPI CoInitializeEx(LPVOID lpReserved, DWORD dwCoInit) +HRESULT WINAPI DECLSPEC_HOTPATCH CoInitializeEx(LPVOID lpReserved, DWORD dwCoInit) { struct oletls *info = COM_CurrentInfo(); HRESULT hr = S_OK; @@ -1997,6 +1997,7 @@ */ HRESULT WINAPI CoDisconnectObject( LPUNKNOWN lpUnk, DWORD reserved ) { + struct stub_manager *manager; HRESULT hr; IMarshal *marshal; APARTMENT *apt; @@ -2017,7 +2018,13 @@ if (!apt) return CO_E_NOTINITIALIZED;
- apartment_disconnectobject(apt, lpUnk); + manager = get_stub_manager_from_object(apt, lpUnk, FALSE); + if (manager) { + stub_manager_disconnect(manager); + /* Release stub manager twice, to remove the apartment reference. */ + stub_manager_int_release(manager); + stub_manager_int_release(manager); + }
/* Note: native is pretty broken here because it just silently * fails, without returning an appropriate error code if the object was @@ -3158,10 +3165,8 @@ REFIID iid, LPVOID *ppv) { + MULTI_QI multi_qi = { iid }; HRESULT hres; - LPCLASSFACTORY lpclf = 0; - APARTMENT *apt; - CLSID clsid;
TRACE("(rclsid=%s, pUnkOuter=%p, dwClsContext=%08x, riid=%s, ppv=%p)\n", debugstr_guid(rclsid), pUnkOuter, dwClsContext, debugstr_guid(iid), ppv); @@ -3169,65 +3174,8 @@ if (ppv==0) return E_POINTER;
- hres = CoGetTreatAsClass(rclsid, &clsid); - if(FAILED(hres)) - clsid = *rclsid; - - *ppv = 0; - - if (!(apt = COM_CurrentApt())) - { - if (!(apt = apartment_find_multi_threaded())) - { - ERR("apartment not initialised\n"); - return CO_E_NOTINITIALIZED; - } - apartment_release(apt); - } - - /* - * The Standard Global Interface Table (GIT) object is a process-wide singleton. - */ - if (IsEqualIID(&clsid, &CLSID_StdGlobalInterfaceTable)) - { - IGlobalInterfaceTable *git = get_std_git(); - hres = IGlobalInterfaceTable_QueryInterface(git, iid, ppv); - if (hres != S_OK) return hres; - - TRACE("Retrieved GIT (%p)\n", *ppv); - return S_OK; - } - - if (IsEqualCLSID(&clsid, &CLSID_ManualResetEvent)) - return ManualResetEvent_Construct(pUnkOuter, iid, ppv); - - /* - * Get a class factory to construct the object we want. - */ - hres = CoGetClassObject(&clsid, - dwClsContext, - NULL, - &IID_IClassFactory, - (LPVOID)&lpclf); - - if (FAILED(hres)) - return hres; - - /* - * Create the object and don't forget to release the factory - */ - hres = IClassFactory_CreateInstance(lpclf, pUnkOuter, iid, ppv); - IClassFactory_Release(lpclf); - if (FAILED(hres)) - { - if (hres == CLASS_E_NOAGGREGATION && pUnkOuter) - FIXME("Class %s does not support aggregation\n", debugstr_guid(&clsid)); - else - FIXME("no instance created for interface %s of class %s, hres is 0x%08x\n", - debugstr_guid(iid), - debugstr_guid(&clsid),hres); - } - + hres = CoCreateInstanceEx(rclsid, pUnkOuter, dwClsContext, NULL, 1, &multi_qi); + *ppv = multi_qi.pItf; return hres; }
@@ -3242,18 +3190,26 @@ } }
-static HRESULT return_multi_qi(IUnknown *unk, DWORD count, MULTI_QI *mqi) -{ - ULONG index, fetched = 0; - - for (index = 0; index < count; index++) +static HRESULT return_multi_qi(IUnknown *unk, DWORD count, MULTI_QI *mqi, BOOL include_unk) +{ + ULONG index = 0, fetched = 0; + + if (include_unk) + { + mqi[0].hr = S_OK; + mqi[0].pItf = unk; + index = fetched = 1; + } + + for (; index < count; index++) { mqi[index].hr = IUnknown_QueryInterface(unk, mqi[index].pIID, (void**)&mqi[index].pItf); if (mqi[index].hr == S_OK) fetched++; }
- IUnknown_Release(unk); + if (!include_unk) + IUnknown_Release(unk);
if (fetched == 0) return E_NOINTERFACE; @@ -3272,39 +3228,83 @@ ULONG cmq, MULTI_QI* pResults) { - IUnknown* pUnk = NULL; - HRESULT hr; - - /* - * Sanity check - */ - if ( (cmq==0) || (pResults==NULL)) - return E_INVALIDARG; - - if (pServerInfo!=NULL) - FIXME("() non-NULL pServerInfo not supported!\n"); - - init_multi_qi(cmq, pResults); - - /* - * Get the object and get its IUnknown pointer. - */ - hr = CoCreateInstance(rclsid, - pUnkOuter, - dwClsContext, - &IID_IUnknown, - (VOID**)&pUnk); - - if (hr != S_OK) - return hr; - - return return_multi_qi(pUnk, cmq, pResults); + IUnknown *unk = NULL; + IClassFactory *cf; + APARTMENT *apt; + CLSID clsid; + HRESULT hres; + + TRACE("(%s %p %x %p %u %p)\n", debugstr_guid(rclsid), pUnkOuter, dwClsContext, pServerInfo, cmq, pResults); + + if (!cmq || !pResults) + return E_INVALIDARG; + + if (pServerInfo) + FIXME("() non-NULL pServerInfo not supported!\n"); + + init_multi_qi(cmq, pResults); + + hres = CoGetTreatAsClass(rclsid, &clsid); + if(FAILED(hres)) + clsid = *rclsid; + + if (!(apt = COM_CurrentApt())) + { + if (!(apt = apartment_find_multi_threaded())) + { + ERR("apartment not initialised\n"); + return CO_E_NOTINITIALIZED; + } + apartment_release(apt); + } + + /* + * The Standard Global Interface Table (GIT) object is a process-wide singleton. + */ + if (IsEqualIID(&clsid, &CLSID_StdGlobalInterfaceTable)) + { + IGlobalInterfaceTable *git = get_std_git(); + TRACE("Retrieving GIT\n"); + return return_multi_qi((IUnknown*)git, cmq, pResults, FALSE); + } + + if (IsEqualCLSID(&clsid, &CLSID_ManualResetEvent)) { + hres = ManualResetEvent_Construct(pUnkOuter, pResults[0].pIID, (void**)&unk); + if (FAILED(hres)) + return hres; + return return_multi_qi(unk, cmq, pResults, TRUE); + } + + /* + * Get a class factory to construct the object we want. + */ + hres = CoGetClassObject(&clsid, dwClsContext, NULL, &IID_IClassFactory, (void**)&cf); + if (FAILED(hres)) + return hres; + + /* + * Create the object and don't forget to release the factory + */ + hres = IClassFactory_CreateInstance(cf, pUnkOuter, pResults[0].pIID, (void**)&unk); + IClassFactory_Release(cf); + if (FAILED(hres)) + { + if (hres == CLASS_E_NOAGGREGATION && pUnkOuter) + FIXME("Class %s does not support aggregation\n", debugstr_guid(&clsid)); + else + FIXME("no instance created for interface %s of class %s, hres is 0x%08x\n", + debugstr_guid(pResults[0].pIID), + debugstr_guid(&clsid),hres); + return hres; + } + + return return_multi_qi(unk, cmq, pResults, TRUE); }
/*********************************************************************** * CoGetInstanceFromFile [OLE32.@] */ -HRESULT WINAPI CoGetInstanceFromFile( +HRESULT WINAPI DECLSPEC_HOTPATCH CoGetInstanceFromFile( COSERVERINFO *server_info, CLSID *rclsid, IUnknown *outer, @@ -3361,7 +3361,7 @@ IPersistFile_Release(pf); }
- return return_multi_qi(unk, count, results); + return return_multi_qi(unk, count, results, FALSE); }
/*********************************************************************** @@ -3424,7 +3424,7 @@ IPersistStorage_Release(ps); }
- return return_multi_qi(unk, count, results); + return return_multi_qi(unk, count, results, FALSE); }
/*********************************************************************** @@ -3583,32 +3583,8 @@ apt = COM_CurrentApt(); if (!apt) return CO_E_NOTINITIALIZED;
- stubmgr = get_stub_manager_from_object(apt, pUnk); - - if (stubmgr) - { - if (fLock) - stub_manager_ext_addref(stubmgr, 1, FALSE); - else - stub_manager_ext_release(stubmgr, 1, FALSE, fLastUnlockReleases); - - stub_manager_int_release(stubmgr); - - return S_OK; - } - else if (fLock) - { - stubmgr = new_stub_manager(apt, pUnk); - - if (stubmgr) - { - stub_manager_ext_addref(stubmgr, 1, FALSE); - stub_manager_int_release(stubmgr); - } - - return S_OK; - } - else + stubmgr = get_stub_manager_from_object(apt, pUnk, fLock); + if (!stubmgr) { WARN("stub object not found %p\n", pUnk); /* Note: native is pretty broken here because it just silently @@ -3616,6 +3592,14 @@ * think that the object was disconnected, when it actually wasn't */ return S_OK; } + + if (fLock) + stub_manager_ext_addref(stubmgr, 1, FALSE); + else + stub_manager_ext_release(stubmgr, 1, FALSE, fLastUnlockReleases); + + stub_manager_int_release(stubmgr); + return S_OK; }
/*********************************************************************** @@ -4366,7 +4350,7 @@ static BOOL COM_PeekMessage(struct apartment *apt, MSG *msg) { /* first try to retrieve messages for incoming COM calls to the apartment window */ - return PeekMessageW(msg, apt->win, 0, 0, PM_REMOVE|PM_NOYIELD) || + return (apt->win && PeekMessageW(msg, apt->win, 0, 0, PM_REMOVE|PM_NOYIELD)) || /* next retrieve other messages necessary for the app to remain responsive */ PeekMessageW(msg, NULL, WM_DDE_FIRST, WM_DDE_LAST, PM_REMOVE|PM_NOYIELD) || PeekMessageW(msg, NULL, 0, 0, PM_QS_PAINT|PM_QS_SENDMESSAGE|PM_REMOVE|PM_NOYIELD);
Modified: trunk/reactos/dll/win32/ole32/compobj_private.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/ole32/compobj_pri... ============================================================================== --- trunk/reactos/dll/win32/ole32/compobj_private.h [iso-8859-1] (original) +++ trunk/reactos/dll/win32/ole32/compobj_private.h [iso-8859-1] Tue Nov 17 10:30:40 2015 @@ -96,6 +96,7 @@ */
ULONG norm_refs; /* refcount of normal marshals (CS lock) */ + BOOL disconnected; /* CoDisconnectObject has been called (CS lock) */ };
/* imported interface proxy */ @@ -174,18 +175,19 @@ /* Stub Manager */
ULONG stub_manager_int_release(struct stub_manager *This) DECLSPEC_HIDDEN; -struct stub_manager *new_stub_manager(APARTMENT *apt, IUnknown *object) DECLSPEC_HIDDEN; ULONG stub_manager_ext_addref(struct stub_manager *m, ULONG refs, BOOL tableweak) DECLSPEC_HIDDEN; ULONG stub_manager_ext_release(struct stub_manager *m, ULONG refs, BOOL tableweak, BOOL last_unlock_releases) DECLSPEC_HIDDEN; -struct ifstub *stub_manager_new_ifstub(struct stub_manager *m, IRpcStubBuffer *sb, IUnknown *iptr, REFIID iid, +struct ifstub *stub_manager_new_ifstub(struct stub_manager *m, IRpcStubBuffer *sb, REFIID iid, DWORD dest_context, void *dest_context_data, MSHLFLAGS flags) DECLSPEC_HIDDEN; struct ifstub *stub_manager_find_ifstub(struct stub_manager *m, REFIID iid, MSHLFLAGS flags) DECLSPEC_HIDDEN; struct stub_manager *get_stub_manager(APARTMENT *apt, OID oid) DECLSPEC_HIDDEN; -struct stub_manager *get_stub_manager_from_object(APARTMENT *apt, void *object) DECLSPEC_HIDDEN; +struct stub_manager *get_stub_manager_from_object(APARTMENT *apt, IUnknown *object, BOOL alloc) DECLSPEC_HIDDEN; BOOL stub_manager_notify_unmarshal(struct stub_manager *m, const IPID *ipid) DECLSPEC_HIDDEN; BOOL stub_manager_is_table_marshaled(struct stub_manager *m, const IPID *ipid) DECLSPEC_HIDDEN; void stub_manager_release_marshal_data(struct stub_manager *m, ULONG refs, const IPID *ipid, BOOL tableweak) DECLSPEC_HIDDEN; -HRESULT ipid_get_dispatch_params(const IPID *ipid, APARTMENT **stub_apt, IRpcStubBuffer **stub, IRpcChannelBuffer **chan, IID *iid, IUnknown **iface) DECLSPEC_HIDDEN; +void stub_manager_disconnect(struct stub_manager *m) DECLSPEC_HIDDEN; +HRESULT ipid_get_dispatch_params(const IPID *ipid, APARTMENT **stub_apt, struct stub_manager **manager, IRpcStubBuffer **stub, + IRpcChannelBuffer **chan, IID *iid, IUnknown **iface) DECLSPEC_HIDDEN; HRESULT start_apartment_remote_unknown(void) DECLSPEC_HIDDEN;
HRESULT marshal_object(APARTMENT *apt, STDOBJREF *stdobjref, REFIID riid, IUnknown *obj, DWORD dest_context, void *dest_context_data, MSHLFLAGS mshlflags) DECLSPEC_HIDDEN; @@ -202,7 +204,7 @@ HRESULT RPC_CreateServerChannel(DWORD dest_context, void *dest_context_data, IRpcChannelBuffer **chan) DECLSPEC_HIDDEN; void RPC_ExecuteCall(struct dispatch_params *params) DECLSPEC_HIDDEN; HRESULT RPC_RegisterInterface(REFIID riid) DECLSPEC_HIDDEN; -void RPC_UnregisterInterface(REFIID riid) DECLSPEC_HIDDEN; +void RPC_UnregisterInterface(REFIID riid, BOOL wait) DECLSPEC_HIDDEN; HRESULT RPC_StartLocalServer(REFCLSID clsid, IStream *stream, BOOL multi_use, void **registration) DECLSPEC_HIDDEN; void RPC_StopLocalServer(void *registration) DECLSPEC_HIDDEN; HRESULT RPC_GetLocalClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv) DECLSPEC_HIDDEN; @@ -225,7 +227,6 @@ APARTMENT *apartment_findfromtid(DWORD tid) DECLSPEC_HIDDEN; DWORD apartment_release(struct apartment *apt) DECLSPEC_HIDDEN; HRESULT apartment_disconnectproxies(struct apartment *apt) DECLSPEC_HIDDEN; -void apartment_disconnectobject(struct apartment *apt, void *object) DECLSPEC_HIDDEN; static inline HRESULT apartment_getoxid(const struct apartment *apt, OXID *oxid) { *oxid = apt->oxid; @@ -306,6 +307,8 @@
extern BOOL actctx_get_miscstatus(const CLSID*, DWORD, DWORD*) DECLSPEC_HIDDEN;
+extern const char *debugstr_formatetc(const FORMATETC *formatetc) DECLSPEC_HIDDEN; + static inline void *heap_alloc(size_t len) { return HeapAlloc(GetProcessHeap(), 0, len);
Modified: trunk/reactos/dll/win32/ole32/datacache.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/ole32/datacache.c... ============================================================================== --- trunk/reactos/dll/win32/ole32/datacache.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/ole32/datacache.c [iso-8859-1] Tue Nov 17 10:30:40 2015 @@ -202,7 +202,7 @@ return CONTAINING_RECORD(iface, DataCache, IAdviseSink_iface); }
-static const char * debugstr_formatetc(const FORMATETC *formatetc) +const char *debugstr_formatetc(const FORMATETC *formatetc) { return wine_dbg_sprintf("{ cfFormat = 0x%x, ptd = %p, dwAspect = %d, lindex = %d, tymed = %d }", formatetc->cfFormat, formatetc->ptd, formatetc->dwAspect, @@ -268,10 +268,10 @@ /* checks that the clipformat and tymed are valid and returns an error if they * aren't and CACHE_S_NOTSUPPORTED if they are valid, but can't be rendered by * DataCache_Draw */ -static HRESULT check_valid_clipformat_and_tymed(CLIPFORMAT cfFormat, DWORD tymed) +static HRESULT check_valid_clipformat_and_tymed(CLIPFORMAT cfFormat, DWORD tymed, BOOL load) { if (!cfFormat || !tymed || - (cfFormat == CF_METAFILEPICT && tymed == TYMED_MFPICT) || + (cfFormat == CF_METAFILEPICT && (tymed == TYMED_MFPICT || load)) || (cfFormat == CF_BITMAP && tymed == TYMED_GDI) || (cfFormat == CF_DIB && tymed == TYMED_HGLOBAL) || (cfFormat == CF_ENHMETAFILE && tymed == TYMED_ENHMF)) @@ -285,11 +285,11 @@ } }
-static HRESULT DataCache_CreateEntry(DataCache *This, const FORMATETC *formatetc, DataCacheEntry **cache_entry) +static HRESULT DataCache_CreateEntry(DataCache *This, const FORMATETC *formatetc, DataCacheEntry **cache_entry, BOOL load) { HRESULT hr;
- hr = check_valid_clipformat_and_tymed(formatetc->cfFormat, formatetc->tymed); + hr = check_valid_clipformat_and_tymed(formatetc->cfFormat, formatetc->tymed, load); if (FAILED(hr)) return hr; if (hr == CACHE_S_FORMATETC_NOTSUPPORTED) @@ -394,7 +394,7 @@ if (length == -1) { DWORD cf; - hr = IStream_Read(stream, &cf, sizeof(cf), 0); + hr = IStream_Read(stream, &cf, sizeof(cf), &read); if (hr != S_OK || read != sizeof(cf)) return DV_E_CLIPFORMAT; *clipformat = cf; @@ -1245,7 +1245,7 @@
cache_entry = DataCache_GetEntryForFormatEtc( This, fmt ); if (!cache_entry) - hr = DataCache_CreateEntry( This, fmt, &cache_entry ); + hr = DataCache_CreateEntry( This, fmt, &cache_entry, TRUE ); if (SUCCEEDED( hr )) { DataCacheEntry_DiscardData( cache_entry ); @@ -1319,7 +1319,10 @@ if (IsEqualCLSID( &stat.clsid, &CLSID_Picture_Dib )) fmt = &static_dib_fmt; else + { + FIXME("unsupported format %s\n", debugstr_guid( &stat.clsid )); return E_FAIL; + }
return add_cache_entry( This, fmt, stm, contents_stream ); } @@ -1351,7 +1354,8 @@ hr = parse_contents_stream( This, pStg, stm ); IStream_Release( stm ); } - else + + if (FAILED(hr)) hr = parse_pres_streams( This, pStg );
if (SUCCEEDED( hr )) @@ -1989,7 +1993,7 @@ return CACHE_S_SAMECACHE; }
- hr = DataCache_CreateEntry(This, pformatetc, &cache_entry); + hr = DataCache_CreateEntry(This, pformatetc, &cache_entry, FALSE);
if (SUCCEEDED(hr)) {
Modified: trunk/reactos/dll/win32/ole32/defaulthandler.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/ole32/defaulthand... ============================================================================== --- trunk/reactos/dll/win32/ole32/defaulthandler.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/ole32/defaulthandler.c [iso-8859-1] Tue Nov 17 10:30:40 2015 @@ -61,7 +61,8 @@ enum object_state { object_state_not_running, - object_state_running + object_state_running, + object_state_deferred_close };
/**************************************************************************** @@ -117,6 +118,7 @@ /* IDataObject delegate */ IDataObject *pDataDelegate; enum object_state object_state; + ULONG in_call;
/* connection cookie for the advise on the delegate OLE object */ DWORD dwAdvConn; @@ -168,6 +170,20 @@ static inline BOOL object_is_running(DefaultHandler *This) { return IRunnableObject_IsRunning(&This->IRunnableObject_iface); +} + +static void DefaultHandler_Stop(DefaultHandler *This); + +static inline void start_object_call(DefaultHandler *This) +{ + This->in_call++; +} + +static inline void end_object_call(DefaultHandler *This) +{ + This->in_call--; + if (This->in_call == 0 && This->object_state == object_state_deferred_close) + DefaultHandler_Stop( This ); }
/********************************************************* @@ -336,7 +352,11 @@ TRACE("(%p, %p)\n", iface, pClientSite);
if (object_is_running(This)) + { + start_object_call( This ); hr = IOleObject_SetClientSite(This->pOleDelegate, pClientSite); + end_object_call( This ); + }
/* * Make sure we release the previous client site if there @@ -399,7 +419,11 @@ debugstr_w(szContainerObj));
if (object_is_running(This)) + { + start_object_call( This ); IOleObject_SetHostNames(This->pOleDelegate, szContainerApp, szContainerObj); + end_object_call( This ); + }
/* Be sure to cleanup before re-assigning the strings. */ HeapFree( GetProcessHeap(), 0, This->containerApp ); @@ -445,17 +469,26 @@ /* undoes the work done by DefaultHandler_Run */ static void DefaultHandler_Stop(DefaultHandler *This) { - if (!object_is_running(This)) + IOleCacheControl *cache_ctrl; + HRESULT hr; + + if (This->object_state == object_state_not_running) return;
+ hr = IUnknown_QueryInterface( This->dataCache, &IID_IOleCacheControl, (void **)&cache_ctrl ); + if (SUCCEEDED(hr)) + { + hr = IOleCacheControl_OnStop( cache_ctrl ); + IOleCacheControl_Release( cache_ctrl ); + } + IOleObject_Unadvise(This->pOleDelegate, This->dwAdvConn); - - /* FIXME: call IOleCache_OnStop */
if (This->dataAdviseHolder) DataAdviseHolder_OnDisconnect(This->dataAdviseHolder);
This->object_state = object_state_not_running; + release_delegates( This ); }
/************************************************************************ @@ -478,10 +511,11 @@ if (!object_is_running(This)) return S_OK;
+ start_object_call( This ); hr = IOleObject_Close(This->pOleDelegate, dwSaveOption); + end_object_call( This );
DefaultHandler_Stop(This); - release_delegates(This);
return hr; } @@ -499,16 +533,18 @@ IMoniker* pmk) { DefaultHandler *This = impl_from_IOleObject(iface); - - TRACE("(%p, %d, %p)\n", - iface, - dwWhichMoniker, - pmk); + HRESULT hr = S_OK; + + TRACE("(%p, %d, %p)\n", iface, dwWhichMoniker, pmk);
if (object_is_running(This)) - return IOleObject_SetMoniker(This->pOleDelegate, dwWhichMoniker, pmk); - - return S_OK; + { + start_object_call( This ); + hr = IOleObject_SetMoniker(This->pOleDelegate, dwWhichMoniker, pmk); + end_object_call( This ); + } + + return hr; }
/************************************************************************ @@ -525,13 +561,19 @@ IMoniker** ppmk) { DefaultHandler *This = impl_from_IOleObject(iface); + HRESULT hr;
TRACE("(%p, %d, %d, %p)\n", iface, dwAssign, dwWhichMoniker, ppmk);
if (object_is_running(This)) - return IOleObject_GetMoniker(This->pOleDelegate, dwAssign, dwWhichMoniker, - ppmk); + { + start_object_call( This ); + hr = IOleObject_GetMoniker(This->pOleDelegate, dwAssign, dwWhichMoniker, + ppmk); + end_object_call( This ); + return hr; + }
/* FIXME: dwWhichMoniker == OLEWHICHMK_CONTAINER only? */ if (This->clientSite) @@ -560,14 +602,20 @@ DWORD dwReserved) { DefaultHandler *This = impl_from_IOleObject(iface); + HRESULT hr = OLE_E_NOTRUNNING;
TRACE("(%p, %p, %d, %d)\n", iface, pDataObject, fCreation, dwReserved);
if (object_is_running(This)) - return IOleObject_InitFromData(This->pOleDelegate, pDataObject, fCreation, + { + start_object_call( This ); + hr = IOleObject_InitFromData(This->pOleDelegate, pDataObject, fCreation, dwReserved); - return OLE_E_NOTRUNNING; + end_object_call( This ); + } + + return hr; }
/************************************************************************ @@ -583,15 +631,20 @@ IDataObject** ppDataObject) { DefaultHandler *This = impl_from_IOleObject(iface); + HRESULT hr = OLE_E_NOTRUNNING;
TRACE("(%p, %d, %p)\n", iface, dwReserved, ppDataObject);
if (object_is_running(This)) - return IOleObject_GetClipboardData(This->pOleDelegate, dwReserved, + { + start_object_call( This ); + hr = IOleObject_GetClipboardData(This->pOleDelegate, dwReserved, ppDataObject); - - return OLE_E_NOTRUNNING; + end_object_call( This ); + } + + return hr; }
static HRESULT WINAPI DefaultHandler_DoVerb( @@ -612,8 +665,12 @@ hr = IRunnableObject_Run(pRunnableObj, NULL); if (FAILED(hr)) return hr;
- return IOleObject_DoVerb(This->pOleDelegate, iVerb, lpmsg, pActiveSite, + start_object_call( This ); + hr = IOleObject_DoVerb(This->pOleDelegate, iVerb, lpmsg, pActiveSite, lindex, hwndParent, lprcPosRect); + end_object_call( This ); + + return hr; }
/************************************************************************ @@ -634,7 +691,11 @@ TRACE("(%p, %p)\n", iface, ppEnumOleVerb);
if (object_is_running(This)) + { + start_object_call( This ); hr = IOleObject_EnumVerbs(This->pOleDelegate, ppEnumOleVerb); + end_object_call( This ); + }
if (hr == OLE_S_USEREG) return OleRegEnumVerbs(&This->clsid, ppEnumOleVerb); @@ -646,6 +707,8 @@ IOleObject* iface) { DefaultHandler *This = impl_from_IOleObject(iface); + HRESULT hr; + TRACE("(%p)\n", iface);
if (!object_is_running(This)) @@ -653,7 +716,12 @@ FIXME("Should run object\n"); return E_NOTIMPL; } - return IOleObject_Update(This->pOleDelegate); + + start_object_call( This ); + hr = IOleObject_Update(This->pOleDelegate); + end_object_call( This ); + + return hr; }
/************************************************************************ @@ -667,12 +735,17 @@ IOleObject* iface) { DefaultHandler *This = impl_from_IOleObject(iface); + HRESULT hr = OLE_E_NOTRUNNING; TRACE("(%p)\n", iface);
if (object_is_running(This)) - return IOleObject_IsUpToDate(This->pOleDelegate); - - return OLE_E_NOTRUNNING; + { + start_object_call( This ); + hr = IOleObject_IsUpToDate(This->pOleDelegate); + end_object_call( This ); + } + + return hr; }
/************************************************************************ @@ -687,11 +760,17 @@ CLSID* pClsid) { DefaultHandler *This = impl_from_IOleObject(iface); + HRESULT hr;
TRACE("(%p, %p)\n", iface, pClsid);
if (object_is_running(This)) - return IOleObject_GetUserClassID(This->pOleDelegate, pClsid); + { + start_object_call( This ); + hr = IOleObject_GetUserClassID(This->pOleDelegate, pClsid); + end_object_call( This ); + return hr; + }
if (!pClsid) return E_POINTER; @@ -715,10 +794,16 @@ LPOLESTR* pszUserType) { DefaultHandler *This = impl_from_IOleObject(iface); + HRESULT hr;
TRACE("(%p, %d, %p)\n", iface, dwFormOfType, pszUserType); if (object_is_running(This)) - return IOleObject_GetUserType(This->pOleDelegate, dwFormOfType, pszUserType); + { + start_object_call( This ); + hr = IOleObject_GetUserType(This->pOleDelegate, dwFormOfType, pszUserType); + end_object_call( This ); + return hr; + }
return OleRegGetUserType(&This->clsid, dwFormOfType, pszUserType); } @@ -736,14 +821,19 @@ SIZEL* psizel) { DefaultHandler *This = impl_from_IOleObject(iface); + HRESULT hr = OLE_E_NOTRUNNING;
TRACE("(%p, %x, (%d x %d))\n", iface, dwDrawAspect, psizel->cx, psizel->cy);
if (object_is_running(This)) - return IOleObject_SetExtent(This->pOleDelegate, dwDrawAspect, psizel); - - return OLE_E_NOTRUNNING; + { + start_object_call( This ); + hr = IOleObject_SetExtent(This->pOleDelegate, dwDrawAspect, psizel); + end_object_call( This ); + } + + return hr; }
/************************************************************************ @@ -768,7 +858,12 @@ TRACE("(%p, %x, %p)\n", iface, dwDrawAspect, psizel);
if (object_is_running(This)) - return IOleObject_GetExtent(This->pOleDelegate, dwDrawAspect, psizel); + { + start_object_call( This ); + hres = IOleObject_GetExtent(This->pOleDelegate, dwDrawAspect, psizel); + end_object_call( This ); + return hres; + }
hres = IUnknown_QueryInterface(This->dataCache, &IID_IViewObject2, (void**)&cacheView); if (FAILED(hres)) @@ -898,7 +993,12 @@ TRACE("(%p, %x, %p)\n", iface, dwAspect, pdwStatus);
if (object_is_running(This)) - return IOleObject_GetMiscStatus(This->pOleDelegate, dwAspect, pdwStatus); + { + start_object_call( This ); + hres = IOleObject_GetMiscStatus(This->pOleDelegate, dwAspect, pdwStatus); + end_object_call( This ); + return hres; + }
hres = OleRegGetMiscStatus(&This->clsid, dwAspect, pdwStatus);
@@ -920,13 +1020,18 @@ struct tagLOGPALETTE* pLogpal) { DefaultHandler *This = impl_from_IOleObject(iface); + HRESULT hr = OLE_E_NOTRUNNING;
TRACE("(%p, %p))\n", iface, pLogpal);
if (object_is_running(This)) - return IOleObject_SetColorScheme(This->pOleDelegate, pLogpal); - - return OLE_E_NOTRUNNING; + { + start_object_call( This ); + hr = IOleObject_SetColorScheme(This->pOleDelegate, pLogpal); + end_object_call( This ); + } + + return hr; }
/********************************************************* @@ -1007,8 +1112,19 @@
IDataObject_Release(cacheDataObject);
- if (FAILED(hres) && This->pDataDelegate) + if (hres == S_OK) return hres; + + if (object_is_running( This )) + { + start_object_call(This); hres = IDataObject_GetData(This->pDataDelegate, pformatetcIn, pmedium); + end_object_call(This); + if (hres == S_OK) return hres; + } + + /* Query running state again, as the object may have closed during _GetData call */ + if (!object_is_running( This )) + hres = OLE_E_NOTRUNNING;
return hres; } @@ -1053,8 +1169,19 @@
IDataObject_Release(cacheDataObject);
- if (FAILED(hres) && This->pDataDelegate) + if (hres == S_OK) return hres; + + if (object_is_running( This )) + { + start_object_call( This ); hres = IDataObject_QueryGetData(This->pDataDelegate, pformatetc); + end_object_call( This ); + if (hres == S_OK) return hres; + } + + /* Query running state again, as the object may have closed during _QueryGetData call */ + if (!object_is_running( This )) + hres = OLE_E_NOTRUNNING;
return hres; } @@ -1072,13 +1199,18 @@ LPFORMATETC pformatetcOut) { DefaultHandler *This = impl_from_IDataObject(iface); + HRESULT hr;
TRACE("(%p, %p, %p)\n", iface, pformatetcIn, pformatetcOut);
- if (!This->pDataDelegate) + if (!object_is_running( This )) return OLE_E_NOTRUNNING;
- return IDataObject_GetCanonicalFormatEtc(This->pDataDelegate, pformatetcIn, pformatetcOut); + start_object_call( This ); + hr = IDataObject_GetCanonicalFormatEtc(This->pDataDelegate, pformatetcIn, pformatetcOut); + end_object_call( This ); + + return hr; }
/************************************************************************ @@ -1163,8 +1295,12 @@ if (!This->dataAdviseHolder) { hres = CreateDataAdviseHolder(&This->dataAdviseHolder); - if (SUCCEEDED(hres) && This->pDataDelegate) + if (SUCCEEDED(hres) && object_is_running( This )) + { + start_object_call( This ); DataAdviseHolder_OnConnect(This->dataAdviseHolder, This->pDataDelegate); + end_object_call( This ); + } }
if (SUCCEEDED(hres)) @@ -1299,6 +1435,7 @@ { DefaultHandler *This = impl_from_IRunnableObject(iface); HRESULT hr; + IOleCacheControl *cache_ctrl;
FIXME("(%p): semi-stub\n", pbc);
@@ -1313,49 +1450,59 @@ if (FAILED(hr)) return hr;
- This->object_state = object_state_running; - hr = IOleObject_Advise(This->pOleDelegate, &This->IAdviseSink_iface, &This->dwAdvConn); - - if (SUCCEEDED(hr) && This->clientSite) + if (FAILED(hr)) goto fail; + + if (This->clientSite) + { hr = IOleObject_SetClientSite(This->pOleDelegate, This->clientSite); - - if (SUCCEEDED(hr)) - { - IOleObject_QueryInterface(This->pOleDelegate, &IID_IPersistStorage, - (void **)&This->pPSDelegate); - if (This->pPSDelegate) - { - if(This->storage_state == storage_state_initialised) - hr = IPersistStorage_InitNew(This->pPSDelegate, This->storage); - else if(This->storage_state == storage_state_loaded) - hr = IPersistStorage_Load(This->pPSDelegate, This->storage); - } - } - - if (SUCCEEDED(hr) && This->containerApp) + if (FAILED(hr)) goto fail; + } + + hr = IOleObject_QueryInterface(This->pOleDelegate, &IID_IPersistStorage, + (void **)&This->pPSDelegate); + if (FAILED(hr)) goto fail; + + if (This->storage_state == storage_state_initialised) + hr = IPersistStorage_InitNew(This->pPSDelegate, This->storage); + else if (This->storage_state == storage_state_loaded) + hr = IPersistStorage_Load(This->pPSDelegate, This->storage); + if (FAILED(hr)) goto fail; + + if (This->containerApp) + { hr = IOleObject_SetHostNames(This->pOleDelegate, This->containerApp, This->containerObj); + if (FAILED(hr)) goto fail; + }
/* FIXME: do more stuff here: * - IOleObject_GetMiscStatus * - IOleObject_GetMoniker - * - IOleCache_OnRun */
- if (SUCCEEDED(hr)) - hr = IOleObject_QueryInterface(This->pOleDelegate, &IID_IDataObject, - (void **)&This->pDataDelegate); - - if (SUCCEEDED(hr) && This->dataAdviseHolder) + hr = IOleObject_QueryInterface(This->pOleDelegate, &IID_IDataObject, + (void **)&This->pDataDelegate); + if (FAILED(hr)) goto fail; + + This->object_state = object_state_running; + + if (This->dataAdviseHolder) + { hr = DataAdviseHolder_OnConnect(This->dataAdviseHolder, This->pDataDelegate); - - if (FAILED(hr)) - { - DefaultHandler_Stop(This); - release_delegates(This); - } - + if (FAILED(hr)) goto fail; + } + + hr = IUnknown_QueryInterface( This->dataCache, &IID_IOleCacheControl, (void **)&cache_ctrl ); + if (FAILED(hr)) goto fail; + hr = IOleCacheControl_OnRun( cache_ctrl, This->pDataDelegate ); + IOleCacheControl_Release( cache_ctrl ); + if (FAILED(hr)) goto fail; + + return hr; + +fail: + DefaultHandler_Stop(This); return hr; }
@@ -1485,9 +1632,14 @@ if (This->oleAdviseHolder) IOleAdviseHolder_SendOnClose(This->oleAdviseHolder);
- DefaultHandler_Stop(This); -} - + if(!This->in_call) + DefaultHandler_Stop(This); + else + { + TRACE("OnClose during call. Deferring shutdown\n"); + This->object_state = object_state_deferred_close; + } +}
/************************************************************************ * DefaultHandler_IPersistStorage_QueryInterface @@ -1541,7 +1693,11 @@ TRACE("(%p)->(%p)\n", iface, clsid);
if(object_is_running(This)) + { + start_object_call( This ); hr = IPersistStorage_GetClassID(This->pPSDelegate, clsid); + end_object_call( This ); + } else hr = IPersistStorage_GetClassID(This->dataCache_PersistStg, clsid);
@@ -1564,7 +1720,11 @@ if(hr != S_FALSE) return hr;
if(object_is_running(This)) + { + start_object_call( This ); hr = IPersistStorage_IsDirty(This->pPSDelegate); + end_object_call( This ); + }
return hr; } @@ -1648,7 +1808,11 @@ hr = IPersistStorage_InitNew(This->dataCache_PersistStg, pStg);
if(SUCCEEDED(hr) && object_is_running(This)) + { + start_object_call( This ); hr = IPersistStorage_InitNew(This->pPSDelegate, pStg); + end_object_call( This ); + }
if(SUCCEEDED(hr)) { @@ -1680,7 +1844,11 @@ hr = IPersistStorage_Load(This->dataCache_PersistStg, pStg);
if(SUCCEEDED(hr) && object_is_running(This)) + { + start_object_call( This ); hr = IPersistStorage_Load(This->pPSDelegate, pStg); + end_object_call( This ); + }
if(SUCCEEDED(hr)) { @@ -1708,7 +1876,11 @@
hr = IPersistStorage_Save(This->dataCache_PersistStg, pStgSave, fSameAsLoad); if(SUCCEEDED(hr) && object_is_running(This)) + { + start_object_call( This ); hr = IPersistStorage_Save(This->pPSDelegate, pStgSave, fSameAsLoad); + end_object_call( This ); + }
return hr; } @@ -1730,7 +1902,11 @@ hr = IPersistStorage_SaveCompleted(This->dataCache_PersistStg, pStgNew);
if(SUCCEEDED(hr) && object_is_running(This)) + { + start_object_call( This ); hr = IPersistStorage_SaveCompleted(This->pPSDelegate, pStgNew); + end_object_call( This ); + }
if(pStgNew) { @@ -1759,7 +1935,11 @@ hr = IPersistStorage_HandsOffStorage(This->dataCache_PersistStg);
if(SUCCEEDED(hr) && object_is_running(This)) + { + start_object_call( This ); hr = IPersistStorage_HandsOffStorage(This->pPSDelegate); + end_object_call( This ); + }
if(This->storage) IStorage_Release(This->storage); This->storage = NULL; @@ -1940,6 +2120,7 @@ This->pPSDelegate = NULL; This->pDataDelegate = NULL; This->object_state = object_state_not_running; + This->in_call = 0;
This->dwAdvConn = 0; This->storage = NULL; @@ -1984,7 +2165,6 @@
/* release delegates */ DefaultHandler_Stop(This); - release_delegates(This);
HeapFree( GetProcessHeap(), 0, This->containerApp ); This->containerApp = NULL;
Modified: trunk/reactos/dll/win32/ole32/filemoniker.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/ole32/filemoniker... ============================================================================== --- trunk/reactos/dll/win32/ole32/filemoniker.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/ole32/filemoniker.c [iso-8859-1] Tue Nov 17 10:30:40 2015 @@ -484,12 +484,12 @@ /* if the requested class was loaded before ! we don't need to reload it */ res = IRunningObjectTable_GetObject(prot,iface,&pObj);
- if (res==S_FALSE){ + if (res != S_OK){ /* first activation of this class */ res=GetClassFile(This->filePathName,&clsID); if (SUCCEEDED(res)){
- res=CoCreateInstance(&clsID,NULL,CLSCTX_ALL,&IID_IPersistFile,(void**)&ppf); + res=CoCreateInstance(&clsID,NULL,CLSCTX_SERVER,&IID_IPersistFile,(void**)&ppf); if (SUCCEEDED(res)){
res=IPersistFile_Load(ppf,This->filePathName,STGM_READ);
Modified: trunk/reactos/dll/win32/ole32/marshal.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/ole32/marshal.c?r... ============================================================================== --- trunk/reactos/dll/win32/ole32/marshal.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/ole32/marshal.c [iso-8859-1] Tue Nov 17 10:30:40 2015 @@ -106,9 +106,7 @@ struct stub_manager *manager; struct ifstub *ifstub; BOOL tablemarshal; - IRpcStubBuffer *stub = NULL; HRESULT hr; - IUnknown *iobject = NULL; /* object of type riid */
hr = apartment_getoxid(apt, &stdobjref->oxid); if (hr != S_OK) @@ -118,78 +116,57 @@ if (hr != S_OK) return hr;
- hr = IUnknown_QueryInterface(object, riid, (void **)&iobject); - if (hr != S_OK) - { - ERR("object doesn't expose interface %s, failing with error 0x%08x\n", - debugstr_guid(riid), hr); - return E_NOINTERFACE; - } - - /* IUnknown doesn't require a stub buffer, because it never goes out on - * the wire */ - if (!IsEqualIID(riid, &IID_IUnknown)) - { - IPSFactoryBuffer *psfb; - - hr = get_facbuf_for_iid(riid, &psfb); - if (hr != S_OK) - { - ERR("couldn't get IPSFactory buffer for interface %s\n", debugstr_guid(riid)); - IUnknown_Release(iobject); - return hr; - } - - hr = IPSFactoryBuffer_CreateStub(psfb, riid, iobject, &stub); - IPSFactoryBuffer_Release(psfb); - if (hr != S_OK) - { - ERR("Failed to create an IRpcStubBuffer from IPSFactory for %s with error 0x%08x\n", - debugstr_guid(riid), hr); - IUnknown_Release(iobject); - return hr; - } - } + if (!(manager = get_stub_manager_from_object(apt, object, TRUE))) + return E_OUTOFMEMORY;
stdobjref->flags = SORF_NULL; if (mshlflags & MSHLFLAGS_TABLEWEAK) stdobjref->flags |= SORFP_TABLEWEAK; if (mshlflags & MSHLFLAGS_NOPING) stdobjref->flags |= SORF_NOPING; - - if ((manager = get_stub_manager_from_object(apt, object))) - TRACE("registering new ifstub on pre-existing manager\n"); - else - { - TRACE("constructing new stub manager\n"); - - manager = new_stub_manager(apt, object); - if (!manager) - { - if (stub) IRpcStubBuffer_Release(stub); - IUnknown_Release(iobject); - return E_OUTOFMEMORY; - } - } stdobjref->oid = manager->oid;
tablemarshal = ((mshlflags & MSHLFLAGS_TABLESTRONG) || (mshlflags & MSHLFLAGS_TABLEWEAK));
/* make sure ifstub that we are creating is unique */ ifstub = stub_manager_find_ifstub(manager, riid, mshlflags); - if (!ifstub) - ifstub = stub_manager_new_ifstub(manager, stub, iobject, riid, dest_context, dest_context_data, mshlflags); - - if (stub) IRpcStubBuffer_Release(stub); - IUnknown_Release(iobject); - - if (!ifstub) - { - stub_manager_int_release(manager); - /* destroy the stub manager if it has no ifstubs by releasing - * zero external references */ - stub_manager_ext_release(manager, 0, FALSE, TRUE); - return E_OUTOFMEMORY; + if (!ifstub) { + IRpcStubBuffer *stub = NULL; + + /* IUnknown doesn't require a stub buffer, because it never goes out on + * the wire */ + if (!IsEqualIID(riid, &IID_IUnknown)) + { + IPSFactoryBuffer *psfb; + + hr = get_facbuf_for_iid(riid, &psfb); + if (hr == S_OK) { + hr = IPSFactoryBuffer_CreateStub(psfb, riid, manager->object, &stub); + IPSFactoryBuffer_Release(psfb); + if (hr != S_OK) + ERR("Failed to create an IRpcStubBuffer from IPSFactory for %s with error 0x%08x\n", + debugstr_guid(riid), hr); + }else { + ERR("couldn't get IPSFactory buffer for interface %s\n", debugstr_guid(riid)); + hr = E_NOINTERFACE; + } + + } + + if (hr == S_OK) { + ifstub = stub_manager_new_ifstub(manager, stub, riid, dest_context, dest_context_data, mshlflags); + if (!ifstub) + hr = E_OUTOFMEMORY; + } + if (stub) IRpcStubBuffer_Release(stub); + + if (hr != S_OK) { + stub_manager_int_release(manager); + /* destroy the stub manager if it has no ifstubs by releasing + * zero external references */ + stub_manager_ext_release(manager, 0, FALSE, TRUE); + return hr; + } }
if (!tablemarshal) @@ -1717,7 +1694,7 @@ OBJREF objref; LPMARSHAL pMarshal;
- TRACE("(%p, %s, %p, %x, %p,", pStream, debugstr_guid(riid), pUnk, + TRACE("(%p, %s, %p, %x, %p, ", pStream, debugstr_guid(riid), pUnk, dwDestContext, pvDestContext); dump_MSHLFLAGS(mshlFlags); TRACE(")\n");
Modified: trunk/reactos/dll/win32/ole32/ole2.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/ole32/ole2.c?rev=... ============================================================================== --- trunk/reactos/dll/win32/ole32/ole2.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/ole32/ole2.c [iso-8859-1] Tue Nov 17 10:30:40 2015 @@ -146,7 +146,7 @@ /*********************************************************************** * OleInitialize (OLE32.@) */ -HRESULT WINAPI OleInitialize(LPVOID reserved) +HRESULT WINAPI DECLSPEC_HOTPATCH OleInitialize(LPVOID reserved) { HRESULT hr;
@@ -1210,7 +1210,7 @@ * Success: S_OK. * Failure: Any HRESULT code. */ -HRESULT WINAPI OleRun(LPUNKNOWN pUnknown) +HRESULT WINAPI DECLSPEC_HOTPATCH OleRun(LPUNKNOWN pUnknown) { IRunnableObject *runable; HRESULT hres; @@ -3016,7 +3016,7 @@
hr = PROPVARIANT_ValidateType(pvarSrc->vt); if (FAILED(hr)) - return hr; + return DISP_E_BADVARTYPE;
/* this will deal with most cases */ *pvarDest = *pvarSrc;
Modified: trunk/reactos/dll/win32/ole32/ole2impl.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/ole32/ole2impl.c?... ============================================================================== --- trunk/reactos/dll/win32/ole32/ole2impl.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/ole32/ole2impl.c [iso-8859-1] Tue Nov 17 10:30:40 2015 @@ -84,7 +84,7 @@ * * FIXME: CF_FILENAME. */ -static HRESULT get_storage(IDataObject *data, IStorage *stg, UINT *src_cf) +static HRESULT get_storage(IDataObject *data, IStorage *stg, UINT *src_cf, BOOL other_fmts) { static const UINT fmt_id[] = { CF_METAFILEPICT, CF_BITMAP, CF_DIB }; UINT i; @@ -94,16 +94,17 @@ IPersistStorage *persist; CLSID clsid;
- *src_cf = 0; + if (src_cf) *src_cf = 0;
/* CF_EMBEDEDOBJECT */ init_fmtetc(&fmt, embedded_object_clipboard_format, TYMED_ISTORAGE); med.tymed = TYMED_ISTORAGE; med.u.pstg = stg; + med.pUnkForRelease = NULL; hr = IDataObject_GetDataHere(data, &fmt, &med); if(SUCCEEDED(hr)) { - *src_cf = embedded_object_clipboard_format; + if (src_cf) *src_cf = embedded_object_clipboard_format; return hr; }
@@ -111,21 +112,25 @@ init_fmtetc(&fmt, embed_source_clipboard_format, TYMED_ISTORAGE); med.tymed = TYMED_ISTORAGE; med.u.pstg = stg; + med.pUnkForRelease = NULL; hr = IDataObject_GetDataHere(data, &fmt, &med); if(SUCCEEDED(hr)) { - *src_cf = embed_source_clipboard_format; + if (src_cf) *src_cf = embed_source_clipboard_format; return hr; }
- for (i = 0; i < sizeof(fmt_id)/sizeof(fmt_id[0]); i++) - { - init_fmtetc(&fmt, fmt_id[i], TYMED_ISTORAGE); - hr = IDataObject_QueryGetData(data, &fmt); - if(SUCCEEDED(hr)) - { - *src_cf = fmt_id[i]; - return hr; + if (other_fmts) + { + for (i = 0; i < sizeof(fmt_id)/sizeof(fmt_id[0]); i++) + { + init_fmtetc(&fmt, fmt_id[i], TYMED_ISTORAGE); + hr = IDataObject_QueryGetData(data, &fmt); + if (SUCCEEDED(hr)) + { + if (src_cf) *src_cf = fmt_id[i]; + return hr; + } } }
@@ -168,7 +173,7 @@ data, debugstr_guid(iid), flags, renderopt, num_cache_fmts, adv_flags, cache_fmts, sink, conns, client_site, stg, obj);
- hr = get_storage(data, stg, &src_cf); + hr = get_storage(data, stg, &src_cf, TRUE); if(FAILED(hr)) return hr;
hr = OleLoad(stg, iid, client_site, obj); @@ -217,6 +222,84 @@ FIXME("%p,%s,%08x,%p,%p,%p,%p: semi-stub\n", data, debugstr_guid(iid), renderopt, fmt, client_site, stg, obj); return OleCreateFromData(data, iid, renderopt, fmt, client_site, stg, obj); +} + +/****************************************************************************** + * OleCreateFromFileEx [OLE32.@] + */ +HRESULT WINAPI OleCreateFromFileEx(REFCLSID clsid, const OLECHAR *filename, REFIID iid, DWORD flags, + DWORD renderopt, ULONG num_fmts, DWORD *adv_flags, FORMATETC *fmts, IAdviseSink *sink, + DWORD *conns, IOleClientSite *client_site, IStorage *stg, void **obj) +{ + HRESULT hr; + IMoniker *mon; + IDataObject *data; + IUnknown *unk = NULL; + IOleCache *cache = NULL; + ULONG i; + + TRACE("cls %s, %s, iid %s, flags %d, render opts %d, num fmts %d, adv flags %p, fmts %p\n", debugstr_guid(clsid), + debugstr_w(filename), debugstr_guid(iid), flags, renderopt, num_fmts, adv_flags, fmts); + TRACE("sink %p, conns %p, client site %p, storage %p, obj %p\n", sink, conns, client_site, stg, obj); + for (i = 0; i < num_fmts; i++) + TRACE("\t%d: fmt %s adv flags %d\n", i, debugstr_formatetc(fmts + i), adv_flags[i]); + + hr = CreateFileMoniker( filename, &mon ); + if (FAILED(hr)) return hr; + + hr = BindMoniker( mon, 0, &IID_IDataObject, (void**)&data ); + IMoniker_Release( mon ); + if (FAILED(hr)) return hr; + + hr = get_storage( data, stg, NULL, FALSE ); + if (FAILED(hr)) goto end; + + hr = OleLoad( stg, &IID_IUnknown, client_site, (void**)&unk ); + if (FAILED(hr)) goto end; + + if (renderopt == OLERENDER_FORMAT) + { + hr = IUnknown_QueryInterface( unk, &IID_IOleCache, (void**)&cache ); + if (FAILED(hr)) goto end; + + for (i = 0; i < num_fmts; i++) + { + STGMEDIUM med; + DWORD dummy_conn; + + memset( &med, 0, sizeof(med) ); + hr = IDataObject_GetData( data, fmts + i, &med ); + if (FAILED(hr)) goto end; + hr = IOleCache_Cache( cache, fmts + i, adv_flags[i], &dummy_conn ); + if (SUCCEEDED(hr)) + hr = IOleCache_SetData( cache, fmts + i, &med, TRUE ); + if (FAILED(hr)) + { + ReleaseStgMedium( &med ); + goto end; + } + } + } + + hr = IUnknown_QueryInterface( unk, iid, obj ); + +end: + if (cache) IOleCache_Release( cache ); + if (unk) IUnknown_Release( unk ); + IDataObject_Release( data ); + return hr; +} + +/****************************************************************************** + * OleCreateFromFile [OLE32.@] + */ +HRESULT WINAPI OleCreateFromFile(REFCLSID clsid, const OLECHAR *filename, REFIID iid, DWORD renderopt, + FORMATETC *fmt, IOleClientSite *client_site, IStorage *storage, void **obj) +{ + DWORD advf = ADVF_PRIMEFIRST; + + return OleCreateFromFileEx(clsid, filename, iid, 0, renderopt, fmt ? 1 : 0, fmt ? &advf : NULL, fmt, + NULL, NULL, client_site, storage, obj); }
/******************************************************************************
Modified: trunk/reactos/dll/win32/ole32/ole2stubs.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/ole32/ole2stubs.c... ============================================================================== --- trunk/reactos/dll/win32/ole32/ole2stubs.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/ole32/ole2stubs.c [iso-8859-1] Tue Nov 17 10:30:40 2015 @@ -45,17 +45,6 @@ }
/****************************************************************************** - * OleCreateFromFile [OLE32.@] - */ -HRESULT WINAPI OleCreateFromFile(REFCLSID rclsid, LPCOLESTR lpszFileName, REFIID riid, - DWORD renderopt, LPFORMATETC lpFormatEtc, LPOLECLIENTSITE pClientSite, LPSTORAGE pStg, LPVOID* ppvObj) -{ - FIXME("(not shown), stub!\n"); - return E_NOTIMPL; -} - - -/****************************************************************************** * OleGetIconOfClass [OLE32.@] */ HGLOBAL WINAPI OleGetIconOfClass(REFCLSID rclsid, LPOLESTR lpszLabel, BOOL fUseTypeAsLabel) @@ -67,7 +56,7 @@ /*********************************************************************** * OleRegEnumFormatEtc [OLE32.@] */ -HRESULT WINAPI OleRegEnumFormatEtc ( +HRESULT WINAPI DECLSPEC_HOTPATCH OleRegEnumFormatEtc ( REFCLSID clsid, DWORD dwDirection, LPENUMFORMATETC* ppenumFormatetc)
Modified: trunk/reactos/dll/win32/ole32/ole32.spec URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/ole32/ole32.spec?... ============================================================================== --- trunk/reactos/dll/win32/ole32/ole32.spec [iso-8859-1] (original) +++ trunk/reactos/dll/win32/ole32/ole32.spec [iso-8859-1] Tue Nov 17 10:30:40 2015 @@ -218,8 +218,8 @@ @ stub OleCreateEx @ stdcall OleCreateFromData(ptr ptr long ptr ptr ptr ptr) @ stdcall OleCreateFromDataEx(ptr ptr long long long ptr ptr ptr ptr ptr ptr ptr) -@ stdcall OleCreateFromFile(ptr ptr ptr long ptr ptr ptr ptr) -@ stub OleCreateFromFileEx +@ stdcall OleCreateFromFile(ptr wstr ptr long ptr ptr ptr ptr) +@ stdcall OleCreateFromFileEx(ptr wstr ptr long long long ptr ptr ptr ptr ptr ptr ptr) @ stdcall OleCreateLink(ptr ptr long ptr ptr ptr ptr) @ stub OleCreateLinkEx @ stdcall OleCreateLinkFromData(ptr ptr long ptr ptr ptr ptr)
Modified: trunk/reactos/dll/win32/ole32/ole32_main.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/ole32/ole32_main.... ============================================================================== --- trunk/reactos/dll/win32/ole32/ole32_main.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/ole32/ole32_main.c [iso-8859-1] Tue Nov 17 10:30:40 2015 @@ -147,3 +147,21 @@
return hmem; } + +/*********************************************************************** + * CoGetActivationState (ole32.@) + */ +HRESULT WINAPI CoGetActivationState(GUID guid, DWORD unknown, DWORD *unknown2) +{ + FIXME("%s, %x, %p\n", debugstr_guid(&guid), unknown, unknown2); + return E_NOTIMPL; +} + +/*********************************************************************** + * CoGetCallState (ole32.@) + */ +HRESULT WINAPI CoGetCallState(int unknown, PULONG unknown2) +{ + FIXME("%d, %p\n", unknown, unknown2); + return E_NOTIMPL; +}
Modified: trunk/reactos/dll/win32/ole32/rpc.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/ole32/rpc.c?rev=6... ============================================================================== --- trunk/reactos/dll/win32/ole32/rpc.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/ole32/rpc.c [iso-8859-1] Tue Nov 17 10:30:40 2015 @@ -661,7 +661,7 @@ }
RpcBindingInqObject(message_state->binding_handle, &ipid); - hr = ipid_get_dispatch_params(&ipid, &apt, &message_state->params.stub, + hr = ipid_get_dispatch_params(&ipid, &apt, NULL, &message_state->params.stub, &message_state->params.chan, &message_state->params.iid, &message_state->params.iface); @@ -1420,6 +1420,7 @@ static void __RPC_STUB dispatch_rpc(RPC_MESSAGE *msg) { struct dispatch_params *params; + struct stub_manager *stub_manager; APARTMENT *apt; IPID ipid; HRESULT hr; @@ -1435,7 +1436,7 @@ return; }
- hr = ipid_get_dispatch_params(&ipid, &apt, ¶ms->stub, ¶ms->chan, + hr = ipid_get_dispatch_params(&ipid, &apt, &stub_manager, ¶ms->stub, ¶ms->chan, ¶ms->iid, ¶ms->iface); if (hr != S_OK) { @@ -1493,6 +1494,7 @@ IRpcStubBuffer_Release(params->stub); HeapFree(GetProcessHeap(), 0, params);
+ stub_manager_int_release(stub_manager); apartment_release(apt);
/* if IRpcStubBuffer_Invoke fails, we should raise an exception to tell @@ -1558,7 +1560,7 @@ }
/* stub unregistration */ -void RPC_UnregisterInterface(REFIID riid) +void RPC_UnregisterInterface(REFIID riid, BOOL wait) { struct registered_if *rif; EnterCriticalSection(&csRegIf); @@ -1568,7 +1570,7 @@ { if (!--rif->refs) { - RpcServerUnregisterIf((RPC_IF_HANDLE)&rif->If, NULL, TRUE); + RpcServerUnregisterIf((RPC_IF_HANDLE)&rif->If, NULL, wait); list_remove(&rif->entry); HeapFree(GetProcessHeap(), 0, rif); }
Modified: trunk/reactos/dll/win32/ole32/storage32.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/ole32/storage32.c... ============================================================================== --- trunk/reactos/dll/win32/ole32/storage32.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/ole32/storage32.c [iso-8859-1] Tue Nov 17 10:30:40 2015 @@ -858,7 +858,7 @@ * IEnumSTATSTGImpl definitions. * * Definition of the implementation structure for the IEnumSTATSTGImpl interface. - * This class allows iterating through the content of a storage and to find + * This class allows iterating through the content of a storage and finding * specific items inside it. */ struct IEnumSTATSTGImpl @@ -890,6 +890,8 @@ { IEnumSTATSTGImpl* const This = impl_from_IEnumSTATSTG(iface);
+ TRACE("%p,%s,%p\n", iface, debugstr_guid(riid), ppvObject); + if (ppvObject==0) return E_INVALIDARG;
@@ -900,9 +902,11 @@ { *ppvObject = &This->IEnumSTATSTG_iface; IEnumSTATSTG_AddRef(&This->IEnumSTATSTG_iface); + TRACE("<-- %p\n", *ppvObject); return S_OK; }
+ TRACE("<-- E_NOINTERFACE\n"); return E_NOINTERFACE; }
@@ -939,6 +943,8 @@ DirEntry entry; HRESULT hr; WCHAR result_name[DIRENTRY_NAME_MAX_LEN]; + + TRACE("%p,%p\n", This, ref);
hr = StorageBaseImpl_ReadDirEntry(This->parentStorage, This->parentStorage->storageDirEntry, &entry); @@ -972,6 +978,7 @@ memcpy(This->name, result_name, sizeof(result_name)); }
+ TRACE("<-- %08x\n", hr); return hr; }
@@ -989,11 +996,16 @@ DirRef currentSearchNode; HRESULT hr=S_OK;
+ TRACE("%p,%u,%p,%p\n", iface, celt, rgelt, pceltFetched); + if ( (rgelt==0) || ( (celt!=1) && (pceltFetched==0) ) ) return E_INVALIDARG;
if (This->parentStorage->reverted) + { + TRACE("<-- STG_E_REVERTED\n"); return STG_E_REVERTED; + }
/* * To avoid the special case, get another pointer to a ULONG value if @@ -1013,14 +1025,18 @@ hr = IEnumSTATSTGImpl_GetNextRef(This, ¤tSearchNode);
if (FAILED(hr) || currentSearchNode == DIRENTRY_NULL) + { + memset(currentReturnStruct, 0, sizeof(*currentReturnStruct)); break; + }
/* * Read the entry from the storage. */ - StorageBaseImpl_ReadDirEntry(This->parentStorage, + hr = StorageBaseImpl_ReadDirEntry(This->parentStorage, currentSearchNode, ¤tEntry); + if (FAILED(hr)) break;
/* * Copy the information to the return buffer. @@ -1040,6 +1056,7 @@ if (SUCCEEDED(hr) && *pceltFetched != celt) hr = S_FALSE;
+ TRACE("<-- %08x (asked %u, got %u)\n", hr, celt, *pceltFetched); return hr; }
@@ -1054,8 +1071,13 @@ DirRef currentSearchNode; HRESULT hr=S_OK;
+ TRACE("%p,%u\n", iface, celt); + if (This->parentStorage->reverted) + { + TRACE("<-- STG_E_REVERTED\n"); return STG_E_REVERTED; + }
while ( (objectFetched < celt) ) { @@ -1070,6 +1092,7 @@ if (SUCCEEDED(hr) && objectFetched != celt) return S_FALSE;
+ TRACE("<-- %08x\n", hr); return hr; }
@@ -1078,8 +1101,13 @@ { IEnumSTATSTGImpl* const This = impl_from_IEnumSTATSTG(iface);
+ TRACE("%p\n", iface); + if (This->parentStorage->reverted) + { + TRACE("<-- STG_E_REVERTED\n"); return STG_E_REVERTED; + }
This->name[0] = 0;
@@ -1095,8 +1123,13 @@ IEnumSTATSTGImpl* const This = impl_from_IEnumSTATSTG(iface); IEnumSTATSTGImpl* newClone;
+ TRACE("%p,%p\n", iface, ppenum); + if (This->parentStorage->reverted) + { + TRACE("<-- STG_E_REVERTED\n"); return STG_E_REVERTED; + }
if (ppenum==0) return E_INVALIDARG; @@ -1186,6 +1219,8 @@ { StorageBaseImpl *This = impl_from_IStorage(iface);
+ TRACE("%p,%s,%p\n", iface, debugstr_guid(riid), ppvObject); + if (!ppvObject) return E_INVALIDARG;
@@ -1206,10 +1241,13 @@ *ppvObject = &This->IDirectWriterLock_iface; } else + { + TRACE("<-- E_NOINTERFACE\n"); return E_NOINTERFACE; + }
IStorage_AddRef(iface); - + TRACE("<-- %p\n", *ppvObject); return S_OK; }
@@ -1392,6 +1430,7 @@ hr = StorageBaseImpl_CopyChildEntryTo( This, data.rightChild, skip_storage, skip_stream, snbExclude, pstgDest );
+ TRACE("<-- %08x\n", hr); return hr; }
@@ -1399,6 +1438,8 @@ { StgStreamImpl *strm;
+ TRACE("%p,%d\n", stg, streamEntry); + LIST_FOR_EACH_ENTRY(strm, &stg->strmHead, StgStreamImpl, StrmListEntry) { if (strm->dirEntry == streamEntry) @@ -1413,6 +1454,8 @@ static BOOL StorageBaseImpl_IsStorageOpen(StorageBaseImpl * stg, DirRef storageEntry) { StorageInternalImpl *childstg; + + TRACE("%p,%d\n", stg, storageEntry);
LIST_FOR_EACH_ENTRY(childstg, &stg->storageHead, StorageInternalImpl, ParentListEntry) { @@ -2218,6 +2261,7 @@ hr = StorageBaseImpl_CopyChildEntryTo( This, data.dirRootEntry, skip_storage, skip_stream, snbExclude, pstgDest );
+ TRACE("<-- %08x\n", hr); return hr; }
@@ -2373,6 +2417,8 @@ HRESULT hr; HRESULT destroyHr = S_OK; StorageInternalImpl *stg, *stg2; + + TRACE("%p,%d\n", parentStorage, indexToDelete);
/* Invalidate any open storage objects. */ LIST_FOR_EACH_ENTRY_SAFE(stg, stg2, &parentStorage->storageHead, StorageInternalImpl, ParentListEntry) @@ -2397,6 +2443,7 @@
if (hr != S_OK) { + TRACE("<-- %08x\n", hr); return hr; }
@@ -2407,6 +2454,7 @@ if (FAILED(hr)) { IStorage_Release(childStorage); + TRACE("<-- %08x\n", hr); return hr; }
@@ -2434,6 +2482,7 @@ IStorage_Release(childStorage); IEnumSTATSTG_Release(elements);
+ TRACE("%08x\n", hr); return destroyHr; }
@@ -2473,6 +2522,7 @@
if (hr!=S_OK) { + TRACE("<-- %08x\n", hr); return(hr); }
@@ -2483,6 +2533,7 @@
if(hr != S_OK) { + TRACE("<-- %08x\n", hr); return hr; }
@@ -2490,7 +2541,7 @@ * Release the stream object. */ IStream_Release(pis); - + TRACE("<-- %08x\n", hr); return S_OK; }
@@ -2500,7 +2551,7 @@ * Strategy: This implementation is built this way for simplicity not for speed. * I always delete the topmost element of the enumeration and adjust * the deleted element pointer all the time. This takes longer to - * do but allow to reinvoke DestroyElement whenever we encounter a + * do but allows reinvoking DestroyElement whenever we encounter a * storage object. The optimisation resides in the usage of another * enumeration strategy that would give all the leaves of a storage * first. (postfix order) @@ -2536,6 +2587,7 @@
if ( entryToDeleteRef == DIRENTRY_NULL ) { + TRACE("<-- STG_E_FILENOTFOUND\n"); return STG_E_FILENOTFOUND; }
@@ -2555,7 +2607,10 @@ }
if (hr!=S_OK) + { + TRACE("<-- %08x\n", hr); return hr; + }
/* * Remove the entry from its parent storage @@ -2574,6 +2629,7 @@ if (SUCCEEDED(hr)) hr = StorageBaseImpl_Flush(This);
+ TRACE("<-- %08x\n", hr); return hr; }
@@ -3428,10 +3484,18 @@ OFFSET_PS_SIZE, &buffer->size.u.LowPart);
- StorageUtl_ReadDWord( - currentEntry, - OFFSET_PS_SIZE_HIGH, - &buffer->size.u.HighPart); + if (This->bigBlockSize < 4096) + { + /* Version 3 files may have junk in the high part of size. */ + buffer->size.u.HighPart = 0; + } + else + { + StorageUtl_ReadDWord( + currentEntry, + OFFSET_PS_SIZE_HIGH, + &buffer->size.u.HighPart); + } }
return readRes; @@ -6004,6 +6068,7 @@ StorageBaseImpl_UnlockTransaction(This->transactedParent, TRUE); }
+ TRACE("<-- %08x\n", hr); return hr; }
@@ -6110,7 +6175,11 @@ TRACE("%x %s l=%x r=%x d=%x\n", index, debugstr_w(data->name), data->leftChild, data->rightChild, data->dirRootEntry);
hr = TransactedSnapshotImpl_EnsureReadEntry(This, index); - if (FAILED(hr)) return hr; + if (FAILED(hr)) + { + TRACE("<-- %08x\n", hr); + return hr; + }
memcpy(&This->entries[index].data, data, sizeof(DirEntry));
@@ -6132,7 +6201,7 @@ This->entries[index].transactedParentEntry = This->entries[index].newTransactedParentEntry = DIRENTRY_NULL; } } - + TRACE("<-- S_OK\n"); return S_OK; }
@@ -6143,7 +6212,11 @@ HRESULT hr;
hr = TransactedSnapshotImpl_EnsureReadEntry(This, index); - if (FAILED(hr)) return hr; + if (FAILED(hr)) + { + TRACE("<-- %08x\n", hr); + return hr; + }
memcpy(data, &This->entries[index].data, sizeof(DirEntry));
@@ -6205,10 +6278,18 @@ HRESULT hr;
hr = TransactedSnapshotImpl_EnsureReadEntry(This, index); - if (FAILED(hr)) return hr; + if (FAILED(hr)) + { + TRACE("<-- %08x\n", hr); + return hr; + }
hr = TransactedSnapshotImpl_MakeStreamDirty(This, index); - if (FAILED(hr)) return hr; + if (FAILED(hr)) + { + TRACE("<-- %08x\n", hr); + return hr; + }
hr = StorageBaseImpl_StreamWriteAt(This->scratch, This->entries[index].stream_entry, offset, size, buffer, bytesWritten); @@ -6218,6 +6299,7 @@ This->entries[index].data.size.QuadPart, offset.QuadPart + size);
+ TRACE("<-- %08x\n", hr); return hr; }
@@ -6228,7 +6310,11 @@ HRESULT hr;
hr = TransactedSnapshotImpl_EnsureReadEntry(This, index); - if (FAILED(hr)) return hr; + if (FAILED(hr)) + { + TRACE("<-- %08x\n", hr); + return hr; + }
if (This->entries[index].data.size.QuadPart == newsize.QuadPart) return S_OK; @@ -6269,6 +6355,7 @@ if (SUCCEEDED(hr)) This->entries[index].data.size = newsize;
+ TRACE("<-- %08x\n", hr); return hr; }
@@ -6280,10 +6367,18 @@ TransactedDirEntry *dst_entry, *src_entry;
hr = TransactedSnapshotImpl_EnsureReadEntry(This, src); - if (FAILED(hr)) return hr; + if (FAILED(hr)) + { + TRACE("<-- %08x\n", hr); + return hr; + }
hr = TransactedSnapshotImpl_EnsureReadEntry(This, dst); - if (FAILED(hr)) return hr; + if (FAILED(hr)) + { + TRACE("<-- %08x\n", hr); + return hr; + }
dst_entry = &This->entries[dst]; src_entry = &This->entries[src]; @@ -6638,7 +6733,7 @@ This->lastTransactionSig = transactionSig+1; } } - + TRACE("<-- %08x\n", hr); return hr; }
@@ -9165,7 +9260,10 @@ count = 0; r = IStream_Read( stm, str, len, &count ); if( FAILED( r ) ) + { + CoTaskMemFree( str ); return r; + } if( count != len ) { CoTaskMemFree( str );
Modified: trunk/reactos/dll/win32/ole32/stubmanager.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/ole32/stubmanager... ============================================================================== --- trunk/reactos/dll/win32/ole32/stubmanager.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/ole32/stubmanager.c [iso-8859-1] Tue Nov 17 10:30:40 2015 @@ -25,6 +25,8 @@
#include "precomp.h"
+#include <wine/exception.h> + WINE_DEFAULT_DEBUG_CHANNEL(ole);
/* generates an ipid in the following format (similar to native version): @@ -51,21 +53,28 @@ }
/* registers a new interface stub COM object with the stub manager and returns registration record */ -struct ifstub *stub_manager_new_ifstub(struct stub_manager *m, IRpcStubBuffer *sb, IUnknown *iptr, REFIID iid, DWORD dest_context, +struct ifstub *stub_manager_new_ifstub(struct stub_manager *m, IRpcStubBuffer *sb, REFIID iid, DWORD dest_context, void *dest_context_data, MSHLFLAGS flags) { struct ifstub *stub; HRESULT hr;
- TRACE("oid=%s, stubbuffer=%p, iptr=%p, iid=%s\n", - wine_dbgstr_longlong(m->oid), sb, iptr, debugstr_guid(iid)); + TRACE("oid=%s, stubbuffer=%p, iid=%s\n", wine_dbgstr_longlong(m->oid), sb, debugstr_guid(iid));
stub = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct ifstub)); if (!stub) return NULL;
+ hr = IUnknown_QueryInterface(m->object, iid, (void **)&stub->iface); + if (hr != S_OK) + { + HeapFree(GetProcessHeap(), 0, stub); + return NULL; + } + hr = RPC_CreateServerChannel(dest_context, dest_context_data, &stub->chan); if (hr != S_OK) { + IUnknown_Release(stub->iface); HeapFree(GetProcessHeap(), 0, stub); return NULL; } @@ -73,8 +82,6 @@ stub->stubbuffer = sb; if (sb) IRpcStubBuffer_AddRef(sb);
- IUnknown_AddRef(iptr); - stub->iface = iptr; stub->flags = flags; stub->iid = *iid;
@@ -102,7 +109,8 @@
list_remove(&ifstub->entry);
- RPC_UnregisterInterface(&ifstub->iid); + if (!m->disconnected) + RPC_UnregisterInterface(&ifstub->iid, TRUE);
if (ifstub->stubbuffer) IRpcStubBuffer_Release(ifstub->stubbuffer); IUnknown_Release(ifstub->iface); @@ -154,7 +162,7 @@ /* creates a new stub manager and adds it into the apartment. caller must * release stub manager when it is no longer required. the apartment and * external refs together take one implicit ref */ -struct stub_manager *new_stub_manager(APARTMENT *apt, IUnknown *object) +static struct stub_manager *new_stub_manager(APARTMENT *apt, IUnknown *object) { struct stub_manager *sm; HRESULT hres; @@ -202,6 +210,7 @@ * the marshalled ifptr. */ sm->extrefs = 0; + sm->disconnected = FALSE;
hres = IUnknown_QueryInterface(object, &IID_IExternalConnection, (void**)&sm->extern_conn); if(FAILED(hres)) @@ -217,6 +226,21 @@ return sm; }
+void stub_manager_disconnect(struct stub_manager *m) +{ + struct ifstub *ifstub; + + EnterCriticalSection(&m->lock); + if (!m->disconnected) + { + LIST_FOR_EACH_ENTRY(ifstub, &m->ifstubs, struct ifstub, entry) + RPC_UnregisterInterface(&ifstub->iid, FALSE); + + m->disconnected = TRUE; + } + LeaveCriticalSection(&m->lock); +} + /* caller must remove stub manager from apartment prior to calling this function */ static void stub_manager_delete(struct stub_manager *m) { @@ -235,7 +259,18 @@ IExternalConnection_Release(m->extern_conn);
CoTaskMemFree(m->oxid_info.psa); - IUnknown_Release(m->object); + + /* Some broken apps crash in object destructors. We have a test showing + * that on winxp+ those crashes are caught and ignored. */ + __TRY + { + IUnknown_Release(m->object); + } + __EXCEPT_PAGE_FAULT + { + ERR("Got page fault when releasing stub!\n"); + } + __ENDTRY
DEBUG_CLEAR_CRITSEC_NAME(&m->lock); DeleteCriticalSection(&m->lock); @@ -284,10 +319,18 @@ /* gets the stub manager associated with an object - caller must have * a reference to the apartment while a reference to the stub manager is held. * it must also call release on the stub manager when it is no longer needed */ -struct stub_manager *get_stub_manager_from_object(APARTMENT *apt, void *object) +struct stub_manager *get_stub_manager_from_object(APARTMENT *apt, IUnknown *obj, BOOL alloc) { struct stub_manager *result = NULL; struct list *cursor; + IUnknown *object; + HRESULT hres; + + hres = IUnknown_QueryInterface(obj, &IID_IUnknown, (void**)&object); + if (FAILED(hres)) { + ERR("QueryInterface(IID_IUnknown failed): %08x\n", hres); + return NULL; + }
EnterCriticalSection(&apt->cs); LIST_FOR_EACH( cursor, &apt->stubmgrs ) @@ -303,37 +346,17 @@ } LeaveCriticalSection(&apt->cs);
- if (result) + if (result) { TRACE("found %p for object %p\n", result, object); - else + }else if (alloc) { + TRACE("not found, creating new stub manager...\n"); + result = new_stub_manager(apt, object); + }else { TRACE("not found for object %p\n", object); - + } + + IUnknown_Release(object); return result; -} - -/* removes the apartment reference to an object, destroying it when no other - * threads have a reference to it */ -void apartment_disconnectobject(struct apartment *apt, void *object) -{ - BOOL found = FALSE; - struct stub_manager *stubmgr; - - EnterCriticalSection(&apt->cs); - LIST_FOR_EACH_ENTRY( stubmgr, &apt->stubmgrs, struct stub_manager, entry ) - { - if (stubmgr->object == object) - { - found = TRUE; - stub_manager_int_release(stubmgr); - break; - } - } - LeaveCriticalSection(&apt->cs); - - if (found) - TRACE("disconnect object %p\n", object); - else - WARN("couldn't find object %p\n", object); }
/* gets the stub manager associated with an object id - caller must have @@ -486,6 +509,7 @@ * release the references to all objects (except iface) if the function * returned success, otherwise no references are returned. */ HRESULT ipid_get_dispatch_params(const IPID *ipid, APARTMENT **stub_apt, + struct stub_manager **manager, IRpcStubBuffer **stub, IRpcChannelBuffer **chan, IID *iid, IUnknown **iface) { @@ -508,7 +532,10 @@ *iid = ifstub->iid; *iface = ifstub->iface;
- stub_manager_int_release(stubmgr); + if (manager) + *manager = stubmgr; + else + stub_manager_int_release(stubmgr); return S_OK; } else @@ -626,7 +653,8 @@ return S_OK; }
- FIXME("No interface for iid %s\n", debugstr_guid(riid)); + if (!IsEqualIID(riid, &IID_IExternalConnection)) + FIXME("No interface for iid %s\n", debugstr_guid(riid));
*ppv = NULL; return E_NOINTERFACE;
Modified: trunk/reactos/dll/win32/ole32/usrmarshal.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/ole32/usrmarshal.... ============================================================================== --- trunk/reactos/dll/win32/ole32/usrmarshal.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/ole32/usrmarshal.c [iso-8859-1] Tue Nov 17 10:30:40 2015 @@ -1472,6 +1472,7 @@ IStream *stm; DWORD size; void *ptr; + IUnknown *orig;
TRACE("(%s, %p, %p, %s)\n", debugstr_user_flags(pFlags), pBuffer, ppunk, debugstr_guid(riid));
@@ -1499,10 +1500,13 @@ memcpy(ptr, pBuffer, size); GlobalUnlock(h);
+ orig = *ppunk; hr = CoUnmarshalInterface(stm, riid, (void**)ppunk); IStream_Release(stm);
if(hr != S_OK) RaiseException(hr, 0, 0, NULL); + + if(orig) IUnknown_Release(orig);
return pBuffer + size; } @@ -1828,7 +1832,10 @@ pBuffer = WdtpInterfacePointer_UserUnmarshal(pFlags, pBuffer, (IUnknown**)&pStgMedium->u.pstm, &IID_IStream); } else + { + if (pStgMedium->u.pstm) IStream_Release( pStgMedium->u.pstm ); pStgMedium->u.pstm = NULL; + } break; case TYMED_ISTORAGE: TRACE("TYMED_ISTORAGE\n"); @@ -1837,7 +1844,10 @@ pBuffer = WdtpInterfacePointer_UserUnmarshal(pFlags, pBuffer, (IUnknown**)&pStgMedium->u.pstg, &IID_IStorage); } else + { + if (pStgMedium->u.pstg) IStorage_Release( pStgMedium->u.pstg ); pStgMedium->u.pstg = NULL; + } break; case TYMED_GDI: TRACE("TYMED_GDI\n"); @@ -1866,9 +1876,10 @@ RaiseException(DV_E_TYMED, 0, 0, NULL); }
- pStgMedium->pUnkForRelease = NULL; if (releaseunk) pBuffer = WdtpInterfacePointer_UserUnmarshal(pFlags, pBuffer, &pStgMedium->pUnkForRelease, &IID_IUnknown); + /* Unlike the IStream / IStorage ifaces, the existing pUnkForRelease + is left intact if a NULL ptr is unmarshalled - see the tests. */
return pBuffer; } @@ -2754,13 +2765,39 @@ return IDataObject_GetData(This, pformatetcIn, pRemoteMedium); }
-HRESULT CALLBACK IDataObject_GetDataHere_Proxy( - IDataObject* This, - FORMATETC *pformatetc, - STGMEDIUM *pmedium) -{ - TRACE("(%p)->(%p, %p)\n", This, pformatetc, pmedium); - return IDataObject_RemoteGetDataHere_Proxy(This, pformatetc, pmedium); +HRESULT CALLBACK IDataObject_GetDataHere_Proxy(IDataObject *iface, FORMATETC *fmt, STGMEDIUM *med) +{ + IUnknown *release; + IStorage *stg = NULL; + HRESULT hr; + + TRACE("(%p)->(%p, %p)\n", iface, fmt, med); + + if ((med->tymed & (TYMED_HGLOBAL | TYMED_FILE | TYMED_ISTREAM | TYMED_ISTORAGE)) == 0) + return DV_E_TYMED; + if (med->tymed != fmt->tymed) + return DV_E_TYMED; + + release = med->pUnkForRelease; + med->pUnkForRelease = NULL; + + if (med->tymed == TYMED_ISTREAM || med->tymed == TYMED_ISTORAGE) + { + stg = med->u.pstg; /* This may actually be a stream, but that's ok */ + if (stg) IStorage_AddRef( stg ); + } + + hr = IDataObject_RemoteGetDataHere_Proxy(iface, fmt, med); + + med->pUnkForRelease = release; + if (stg) + { + if (med->u.pstg) + IStorage_Release( med->u.pstg ); + med->u.pstg = stg; + } + + return hr; }
HRESULT __RPC_STUB IDataObject_GetDataHere_Stub(
Modified: trunk/reactos/media/doc/README.WINE URL: http://svn.reactos.org/svn/reactos/trunk/reactos/media/doc/README.WINE?rev=6... ============================================================================== --- trunk/reactos/media/doc/README.WINE [iso-8859-1] (original) +++ trunk/reactos/media/doc/README.WINE [iso-8859-1] Tue Nov 17 10:30:40 2015 @@ -144,7 +144,7 @@ reactos/dll/win32/objsel # Synced to WineStaging-1.7.47 reactos/dll/win32/odbc32 # Synced to WineStaging-1.7.37. Depends on port of Linux ODBC. reactos/dll/win32/odbccp32 # Synced to WineStaging-1.7.47 -reactos/dll/win32/ole32 # 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/olecli32 # Synced to WineStaging-1.7.47