[OLE32] Sync with Wine Staging 1.7.55. CORE-10536

svn path=/trunk/; revision=69908
This commit is contained in:
Amine Khaldi 2015-11-17 10:30:40 +00:00
parent ca6b297569
commit 40c6100667
16 changed files with 759 additions and 356 deletions

View file

@ -1003,7 +1003,7 @@ static HRESULT get_local_server_stream(APARTMENT *apt, IStream **ret)
* SEE ALSO
* CoRegisterClassObject
*/
HRESULT WINAPI CoRevokeClassObject(
HRESULT WINAPI DECLSPEC_HOTPATCH CoRevokeClassObject(
DWORD dwRegister)
{
HRESULT hr = E_INVALIDARG;
@ -1851,7 +1851,7 @@ HRESULT WINAPI CoInitialize(LPVOID lpReserved)
* 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 @@ void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void)
*/
HRESULT WINAPI CoDisconnectObject( LPUNKNOWN lpUnk, DWORD reserved )
{
struct stub_manager *manager;
HRESULT hr;
IMarshal *marshal;
APARTMENT *apt;
@ -2017,7 +2018,13 @@ HRESULT WINAPI CoDisconnectObject( LPUNKNOWN lpUnk, DWORD reserved )
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 @@ HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(
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 @@ HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(
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 void init_multi_qi(DWORD count, MULTI_QI *mqi)
}
}
static HRESULT return_multi_qi(IUnknown *unk, DWORD count, MULTI_QI *mqi)
static HRESULT return_multi_qi(IUnknown *unk, DWORD count, MULTI_QI *mqi, BOOL include_unk)
{
ULONG index, fetched = 0;
ULONG index = 0, fetched = 0;
for (index = 0; index < count; index++)
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 @@ HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstanceEx(
ULONG cmq,
MULTI_QI* pResults)
{
IUnknown* pUnk = NULL;
HRESULT hr;
IUnknown *unk = NULL;
IClassFactory *cf;
APARTMENT *apt;
CLSID clsid;
HRESULT hres;
/*
* Sanity check
*/
if ( (cmq==0) || (pResults==NULL))
return E_INVALIDARG;
TRACE("(%s %p %x %p %u %p)\n", debugstr_guid(rclsid), pUnkOuter, dwClsContext, pServerInfo, cmq, pResults);
if (pServerInfo!=NULL)
FIXME("() non-NULL pServerInfo not supported!\n");
if (!cmq || !pResults)
return E_INVALIDARG;
init_multi_qi(cmq, pResults);
if (pServerInfo)
FIXME("() non-NULL pServerInfo not supported!\n");
/*
* Get the object and get its IUnknown pointer.
*/
hr = CoCreateInstance(rclsid,
pUnkOuter,
dwClsContext,
&IID_IUnknown,
(VOID**)&pUnk);
init_multi_qi(cmq, pResults);
if (hr != S_OK)
return hr;
hres = CoGetTreatAsClass(rclsid, &clsid);
if(FAILED(hres))
clsid = *rclsid;
return return_multi_qi(pUnk, cmq, pResults);
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 @@ HRESULT WINAPI CoGetInstanceFromFile(
IPersistFile_Release(pf);
}
return return_multi_qi(unk, count, results);
return return_multi_qi(unk, count, results, FALSE);
}
/***********************************************************************
@ -3424,7 +3424,7 @@ HRESULT WINAPI CoGetInstanceFromIStorage(
IPersistStorage_Release(ps);
}
return return_multi_qi(unk, count, results);
return return_multi_qi(unk, count, results, FALSE);
}
/***********************************************************************
@ -3583,32 +3583,8 @@ HRESULT WINAPI CoLockObjectExternal(
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 @@ HRESULT WINAPI CoLockObjectExternal(
* 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 @@ HRESULT WINAPI CoRevertToSelf(void)
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);

View file

@ -96,6 +96,7 @@ struct stub_manager
*/
ULONG norm_refs; /* refcount of normal marshals (CS lock) */
BOOL disconnected; /* CoDisconnectObject has been called (CS lock) */
};
/* imported interface proxy */
@ -174,18 +175,19 @@ HRESULT FTMarshalCF_Create(REFIID riid, LPVOID *ppv) DECLSPEC_HIDDEN;
/* 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_CreateClientChannel(const OXID *oxid, const IPID *ipid,
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_findfromoxid(OXID oxid, BOOL ref) DECLSPEC_HIDDEN;
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 LSTATUS open_classes_key(HKEY, const WCHAR *, REGSAM, HKEY *) DECLSPEC_HI
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);

View file

@ -202,7 +202,7 @@ static inline DataCache *impl_from_IAdviseSink( IAdviseSink *iface )
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 @@ static DataCacheEntry *DataCache_GetEntryForFormatEtc(DataCache *This, const FOR
/* 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 check_valid_clipformat_and_tymed(CLIPFORMAT cfFormat, DWORD tymed
}
}
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 @@ static HRESULT read_clipformat(IStream *stream, CLIPFORMAT *clipformat)
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 @@ static HRESULT add_cache_entry( DataCache *This, const FORMATETC *fmt, IStream *
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 @@ static HRESULT parse_contents_stream( DataCache *This, IStorage *stg, IStream *s
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 @@ static HRESULT WINAPI DataCache_Load( IPersistStorage *iface, IStorage *pStg )
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 @@ static HRESULT WINAPI DataCache_Cache(
return CACHE_S_SAMECACHE;
}
hr = DataCache_CreateEntry(This, pformatetc, &cache_entry);
hr = DataCache_CreateEntry(This, pformatetc, &cache_entry, FALSE);
if (SUCCEEDED(hr))
{

View file

@ -61,7 +61,8 @@ enum storage_state
enum object_state
{
object_state_not_running,
object_state_running
object_state_running,
object_state_deferred_close
};
/****************************************************************************
@ -117,6 +118,7 @@ struct DefaultHandler
/* IDataObject delegate */
IDataObject *pDataDelegate;
enum object_state object_state;
ULONG in_call;
/* connection cookie for the advise on the delegate OLE object */
DWORD dwAdvConn;
@ -170,6 +172,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 );
}
/*********************************************************
* Method implementation for the non delegating IUnknown
* part of the DefaultHandler class.
@ -336,7 +352,11 @@ static HRESULT WINAPI DefaultHandler_SetClientSite(
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 @@ static HRESULT WINAPI DefaultHandler_SetHostNames(
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 @@ static void release_delegates(DefaultHandler *This)
/* 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;
IOleObject_Unadvise(This->pOleDelegate, This->dwAdvConn);
hr = IUnknown_QueryInterface( This->dataCache, &IID_IOleCacheControl, (void **)&cache_ctrl );
if (SUCCEEDED(hr))
{
hr = IOleCacheControl_OnStop( cache_ctrl );
IOleCacheControl_Release( cache_ctrl );
}
/* FIXME: call IOleCache_OnStop */
IOleObject_Unadvise(This->pOleDelegate, This->dwAdvConn);
if (This->dataAdviseHolder)
DataAdviseHolder_OnDisconnect(This->dataAdviseHolder);
This->object_state = object_state_not_running;
release_delegates( This );
}
/************************************************************************
@ -478,10 +511,11 @@ static HRESULT WINAPI DefaultHandler_Close(
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 @@ static HRESULT WINAPI DefaultHandler_SetMoniker(
IMoniker* pmk)
{
DefaultHandler *This = impl_from_IOleObject(iface);
HRESULT hr = S_OK;
TRACE("(%p, %d, %p)\n",
iface,
dwWhichMoniker,
pmk);
TRACE("(%p, %d, %p)\n", iface, dwWhichMoniker, pmk);
if (object_is_running(This))
return IOleObject_SetMoniker(This->pOleDelegate, dwWhichMoniker, pmk);
{
start_object_call( This );
hr = IOleObject_SetMoniker(This->pOleDelegate, dwWhichMoniker, pmk);
end_object_call( This );
}
return S_OK;
return hr;
}
/************************************************************************
@ -525,13 +561,19 @@ static HRESULT WINAPI DefaultHandler_GetMoniker(
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 @@ static HRESULT WINAPI DefaultHandler_InitFromData(
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 @@ static HRESULT WINAPI DefaultHandler_GetClipboardData(
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);
end_object_call( This );
}
return OLE_E_NOTRUNNING;
return hr;
}
static HRESULT WINAPI DefaultHandler_DoVerb(
@ -612,8 +665,12 @@ static HRESULT WINAPI DefaultHandler_DoVerb(
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 @@ static HRESULT WINAPI DefaultHandler_EnumVerbs(
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 @@ static HRESULT WINAPI DefaultHandler_Update(
IOleObject* iface)
{
DefaultHandler *This = impl_from_IOleObject(iface);
HRESULT hr;
TRACE("(%p)\n", iface);
if (!object_is_running(This))
@ -653,7 +716,12 @@ static HRESULT WINAPI DefaultHandler_Update(
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 @@ static HRESULT WINAPI DefaultHandler_IsUpToDate(
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);
{
start_object_call( This );
hr = IOleObject_IsUpToDate(This->pOleDelegate);
end_object_call( This );
}
return OLE_E_NOTRUNNING;
return hr;
}
/************************************************************************
@ -687,11 +760,17 @@ static HRESULT WINAPI DefaultHandler_GetUserClassID(
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 @@ static HRESULT WINAPI DefaultHandler_GetUserType(
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 @@ static HRESULT WINAPI DefaultHandler_SetExtent(
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);
{
start_object_call( This );
hr = IOleObject_SetExtent(This->pOleDelegate, dwDrawAspect, psizel);
end_object_call( This );
}
return OLE_E_NOTRUNNING;
return hr;
}
/************************************************************************
@ -768,7 +858,12 @@ static HRESULT WINAPI DefaultHandler_GetExtent(
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 @@ static HRESULT WINAPI DefaultHandler_GetMiscStatus(
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 @@ static HRESULT WINAPI DefaultHandler_SetColorScheme(
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);
{
start_object_call( This );
hr = IOleObject_SetColorScheme(This->pOleDelegate, pLogpal);
end_object_call( This );
}
return OLE_E_NOTRUNNING;
return hr;
}
/*********************************************************
@ -1007,8 +1112,19 @@ static HRESULT WINAPI DefaultHandler_GetData(
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 @@ static HRESULT WINAPI DefaultHandler_QueryGetData(
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 @@ static HRESULT WINAPI DefaultHandler_GetCanonicalFormatEtc(
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 @@ static HRESULT WINAPI DefaultHandler_DAdvise(
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 @@ static HRESULT WINAPI DefaultHandler_Run(
{
DefaultHandler *This = impl_from_IRunnableObject(iface);
HRESULT hr;
IOleCacheControl *cache_ctrl;
FIXME("(%p): semi-stub\n", pbc);
@ -1313,49 +1450,59 @@ static HRESULT WINAPI DefaultHandler_Run(
if (FAILED(hr))
return hr;
This->object_state = object_state_running;
hr = IOleObject_Advise(This->pOleDelegate, &This->IAdviseSink_iface, &This->dwAdvConn);
if (FAILED(hr)) goto fail;
if (SUCCEEDED(hr) && This->clientSite)
hr = IOleObject_SetClientSite(This->pOleDelegate, This->clientSite);
if (SUCCEEDED(hr))
if (This->clientSite)
{
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);
}
hr = IOleObject_SetClientSite(This->pOleDelegate, This->clientSite);
if (FAILED(hr)) goto fail;
}
if (SUCCEEDED(hr) && This->containerApp)
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);
hr = IOleObject_QueryInterface(This->pOleDelegate, &IID_IDataObject,
(void **)&This->pDataDelegate);
if (FAILED(hr)) goto fail;
if (SUCCEEDED(hr) && This->dataAdviseHolder)
hr = DataAdviseHolder_OnConnect(This->dataAdviseHolder, This->pDataDelegate);
This->object_state = object_state_running;
if (FAILED(hr))
if (This->dataAdviseHolder)
{
DefaultHandler_Stop(This);
release_delegates(This);
hr = DataAdviseHolder_OnConnect(This->dataAdviseHolder, This->pDataDelegate);
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,10 +1632,15 @@ static void WINAPI DefaultHandler_IAdviseSink_OnClose(
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 @@ static HRESULT WINAPI DefaultHandler_IPersistStorage_GetClassID(
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 @@ static HRESULT WINAPI DefaultHandler_IPersistStorage_IsDirty(
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 @@ static HRESULT WINAPI DefaultHandler_IPersistStorage_InitNew(
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 @@ static HRESULT WINAPI DefaultHandler_IPersistStorage_Load(
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 @@ static HRESULT WINAPI DefaultHandler_IPersistStorage_Save(
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 @@ static HRESULT WINAPI DefaultHandler_IPersistStorage_SaveCompleted(
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 @@ static HRESULT WINAPI DefaultHandler_IPersistStorage_HandsOffStorage(
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 @@ static DefaultHandler* DefaultHandler_Construct(
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 @@ static void DefaultHandler_Destroy(
/* release delegates */
DefaultHandler_Stop(This);
release_delegates(This);
HeapFree( GetProcessHeap(), 0, This->containerApp );
This->containerApp = NULL;

View file

@ -484,12 +484,12 @@ FileMonikerImpl_BindToObject(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft
/* 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);

View file

@ -106,9 +106,7 @@ HRESULT marshal_object(APARTMENT *apt, STDOBJREF *stdobjref, REFIID riid, IUnkno
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 @@ HRESULT marshal_object(APARTMENT *apt, STDOBJREF *stdobjref, REFIID riid, IUnkno
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 (!ifstub) {
IRpcStubBuffer *stub = NULL;
if (stub) IRpcStubBuffer_Release(stub);
IUnknown_Release(iobject);
/* IUnknown doesn't require a stub buffer, because it never goes out on
* the wire */
if (!IsEqualIID(riid, &IID_IUnknown))
{
IPSFactoryBuffer *psfb;
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;
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 @@ HRESULT WINAPI CoMarshalInterface(IStream *pStream, REFIID riid, IUnknown *pUnk,
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");

View file

@ -146,7 +146,7 @@ DWORD WINAPI OleBuildVersion(void)
/***********************************************************************
* OleInitialize (OLE32.@)
*/
HRESULT WINAPI OleInitialize(LPVOID reserved)
HRESULT WINAPI DECLSPEC_HOTPATCH OleInitialize(LPVOID reserved)
{
HRESULT hr;
@ -1210,7 +1210,7 @@ HRESULT WINAPI OleSetContainedObject(
* 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 @@ HRESULT WINAPI PropVariantCopy(PROPVARIANT *pvarDest, /* [out] */
hr = PROPVARIANT_ValidateType(pvarSrc->vt);
if (FAILED(hr))
return hr;
return DISP_E_BADVARTYPE;
/* this will deal with most cases */
*pvarDest = *pvarSrc;

View file

@ -84,7 +84,7 @@ static inline void init_fmtetc(FORMATETC *fmt, CLIPFORMAT cf, TYMED tymed)
*
* 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 @@ static HRESULT get_storage(IDataObject *data, IStorage *stg, UINT *src_cf)
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 @@ static HRESULT get_storage(IDataObject *data, IStorage *stg, UINT *src_cf)
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++)
if (other_fmts)
{
init_fmtetc(&fmt, fmt_id[i], TYMED_ISTORAGE);
hr = IDataObject_QueryGetData(data, &fmt);
if(SUCCEEDED(hr))
for (i = 0; i < sizeof(fmt_id)/sizeof(fmt_id[0]); i++)
{
*src_cf = fmt_id[i];
return hr;
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 @@ HRESULT WINAPI OleCreateFromDataEx(IDataObject *data, REFIID iid, DWORD flags,
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);
@ -219,6 +224,84 @@ HRESULT WINAPI OleCreateStaticFromData(IDataObject *data, REFIID iid,
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);
}
/******************************************************************************
* OleDuplicateData [OLE32.@]
*

View file

@ -44,17 +44,6 @@ HRESULT WINAPI OleCreateLink(LPMONIKER pmkLinkSrc, REFIID riid, DWORD renderopt,
return E_NOTIMPL;
}
/******************************************************************************
* 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.@]
*/
@ -67,7 +56,7 @@ HGLOBAL WINAPI OleGetIconOfClass(REFCLSID rclsid, LPOLESTR lpszLabel, BOOL fUseT
/***********************************************************************
* OleRegEnumFormatEtc [OLE32.@]
*/
HRESULT WINAPI OleRegEnumFormatEtc (
HRESULT WINAPI DECLSPEC_HOTPATCH OleRegEnumFormatEtc (
REFCLSID clsid,
DWORD dwDirection,
LPENUMFORMATETC* ppenumFormatetc)

View file

@ -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)

View file

@ -147,3 +147,21 @@ HGLOBAL WINAPI OleMetafilePictFromIconAndLabel(HICON hIcon, LPOLESTR lpszLabel,
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;
}

View file

@ -661,7 +661,7 @@ static HRESULT WINAPI ClientRpcChannelBuffer_GetBuffer(LPRPCCHANNELBUFFER iface,
}
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 @@ exit:
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 @@ static void __RPC_STUB dispatch_rpc(RPC_MESSAGE *msg)
return;
}
hr = ipid_get_dispatch_params(&ipid, &apt, &params->stub, &params->chan,
hr = ipid_get_dispatch_params(&ipid, &apt, &stub_manager, &params->stub, &params->chan,
&params->iid, &params->iface);
if (hr != S_OK)
{
@ -1493,6 +1494,7 @@ static void __RPC_STUB dispatch_rpc(RPC_MESSAGE *msg)
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 @@ HRESULT RPC_RegisterInterface(REFIID riid)
}
/* stub unregistration */
void RPC_UnregisterInterface(REFIID riid)
void RPC_UnregisterInterface(REFIID riid, BOOL wait)
{
struct registered_if *rif;
EnterCriticalSection(&csRegIf);
@ -1568,7 +1570,7 @@ void RPC_UnregisterInterface(REFIID riid)
{
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);
}

View file

@ -858,7 +858,7 @@ static HRESULT removeFromTree(
* 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 @@ static HRESULT WINAPI IEnumSTATSTGImpl_QueryInterface(
{
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 @@ static HRESULT WINAPI IEnumSTATSTGImpl_QueryInterface(
{
*ppvObject = &This->IEnumSTATSTG_iface;
IEnumSTATSTG_AddRef(&This->IEnumSTATSTG_iface);
TRACE("<-- %p\n", *ppvObject);
return S_OK;
}
TRACE("<-- E_NOINTERFACE\n");
return E_NOINTERFACE;
}
@ -940,6 +944,8 @@ static HRESULT IEnumSTATSTGImpl_GetNextRef(
HRESULT hr;
WCHAR result_name[DIRENTRY_NAME_MAX_LEN];
TRACE("%p,%p\n", This, ref);
hr = StorageBaseImpl_ReadDirEntry(This->parentStorage,
This->parentStorage->storageDirEntry, &entry);
searchNode = entry.dirRootEntry;
@ -972,6 +978,7 @@ static HRESULT IEnumSTATSTGImpl_GetNextRef(
memcpy(This->name, result_name, sizeof(result_name));
}
TRACE("<-- %08x\n", hr);
return hr;
}
@ -989,11 +996,16 @@ static HRESULT WINAPI IEnumSTATSTGImpl_Next(
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 @@ static HRESULT WINAPI IEnumSTATSTGImpl_Next(
hr = IEnumSTATSTGImpl_GetNextRef(This, &currentSearchNode);
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,
&currentEntry);
if (FAILED(hr)) break;
/*
* Copy the information to the return buffer.
@ -1040,6 +1056,7 @@ static HRESULT WINAPI IEnumSTATSTGImpl_Next(
if (SUCCEEDED(hr) && *pceltFetched != celt)
hr = S_FALSE;
TRACE("<-- %08x (asked %u, got %u)\n", hr, celt, *pceltFetched);
return hr;
}
@ -1054,8 +1071,13 @@ static HRESULT WINAPI IEnumSTATSTGImpl_Skip(
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 @@ static HRESULT WINAPI IEnumSTATSTGImpl_Skip(
if (SUCCEEDED(hr) && objectFetched != celt)
return S_FALSE;
TRACE("<-- %08x\n", hr);
return hr;
}
@ -1078,8 +1101,13 @@ static HRESULT WINAPI IEnumSTATSTGImpl_Reset(
{
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 @@ static HRESULT WINAPI IEnumSTATSTGImpl_Clone(
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 @@ static HRESULT WINAPI StorageBaseImpl_QueryInterface(
{
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 @@ static HRESULT WINAPI StorageBaseImpl_QueryInterface(
*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 @@ static HRESULT StorageBaseImpl_CopyChildEntryTo(StorageBaseImpl *This,
hr = StorageBaseImpl_CopyChildEntryTo( This, data.rightChild, skip_storage,
skip_stream, snbExclude, pstgDest );
TRACE("<-- %08x\n", hr);
return hr;
}
@ -1399,6 +1438,8 @@ static BOOL StorageBaseImpl_IsStreamOpen(StorageBaseImpl * stg, DirRef streamEnt
{
StgStreamImpl *strm;
TRACE("%p,%d\n", stg, streamEntry);
LIST_FOR_EACH_ENTRY(strm, &stg->strmHead, StgStreamImpl, StrmListEntry)
{
if (strm->dirEntry == streamEntry)
@ -1414,6 +1455,8 @@ static BOOL StorageBaseImpl_IsStorageOpen(StorageBaseImpl * stg, DirRef storageE
{
StorageInternalImpl *childstg;
TRACE("%p,%d\n", stg, storageEntry);
LIST_FOR_EACH_ENTRY(childstg, &stg->storageHead, StorageInternalImpl, ParentListEntry)
{
if (childstg->base.storageDirEntry == storageEntry)
@ -2218,6 +2261,7 @@ static HRESULT StorageBaseImpl_CopyStorageEntryTo(StorageBaseImpl *This,
hr = StorageBaseImpl_CopyChildEntryTo( This, data.dirRootEntry, skip_storage,
skip_stream, snbExclude, pstgDest );
TRACE("<-- %08x\n", hr);
return hr;
}
@ -2374,6 +2418,8 @@ static HRESULT deleteStorageContents(
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 @@ static HRESULT deleteStorageContents(
if (hr != S_OK)
{
TRACE("<-- %08x\n", hr);
return hr;
}
@ -2407,6 +2454,7 @@ static HRESULT deleteStorageContents(
if (FAILED(hr))
{
IStorage_Release(childStorage);
TRACE("<-- %08x\n", hr);
return hr;
}
@ -2434,6 +2482,7 @@ static HRESULT deleteStorageContents(
IStorage_Release(childStorage);
IEnumSTATSTG_Release(elements);
TRACE("%08x\n", hr);
return destroyHr;
}
@ -2473,6 +2522,7 @@ static HRESULT deleteStreamContents(
if (hr!=S_OK)
{
TRACE("<-- %08x\n", hr);
return(hr);
}
@ -2483,6 +2533,7 @@ static HRESULT deleteStreamContents(
if(hr != S_OK)
{
TRACE("<-- %08x\n", hr);
return hr;
}
@ -2490,7 +2541,7 @@ static HRESULT deleteStreamContents(
* Release the stream object.
*/
IStream_Release(pis);
TRACE("<-- %08x\n", hr);
return S_OK;
}
@ -2500,7 +2551,7 @@ static HRESULT deleteStreamContents(
* 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 @@ static HRESULT WINAPI StorageBaseImpl_DestroyElement(
if ( entryToDeleteRef == DIRENTRY_NULL )
{
TRACE("<-- STG_E_FILENOTFOUND\n");
return STG_E_FILENOTFOUND;
}
@ -2555,7 +2607,10 @@ static HRESULT WINAPI StorageBaseImpl_DestroyElement(
}
if (hr!=S_OK)
{
TRACE("<-- %08x\n", hr);
return hr;
}
/*
* Remove the entry from its parent storage
@ -2574,6 +2629,7 @@ static HRESULT WINAPI StorageBaseImpl_DestroyElement(
if (SUCCEEDED(hr))
hr = StorageBaseImpl_Flush(This);
TRACE("<-- %08x\n", hr);
return hr;
}
@ -3428,10 +3484,18 @@ static HRESULT StorageImpl_ReadDirEntry(
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 @@ end:
StorageBaseImpl_UnlockTransaction(This->transactedParent, TRUE);
}
TRACE("<-- %08x\n", hr);
return hr;
}
@ -6110,7 +6175,11 @@ static HRESULT TransactedSnapshotImpl_WriteDirEntry(StorageBaseImpl *base,
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 @@ static HRESULT TransactedSnapshotImpl_WriteDirEntry(StorageBaseImpl *base,
This->entries[index].transactedParentEntry = This->entries[index].newTransactedParentEntry = DIRENTRY_NULL;
}
}
TRACE("<-- S_OK\n");
return S_OK;
}
@ -6143,7 +6212,11 @@ static HRESULT TransactedSnapshotImpl_ReadDirEntry(StorageBaseImpl *base,
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 @@ static HRESULT TransactedSnapshotImpl_StreamWriteAt(StorageBaseImpl *base,
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 @@ static HRESULT TransactedSnapshotImpl_StreamWriteAt(StorageBaseImpl *base,
This->entries[index].data.size.QuadPart,
offset.QuadPart + size);
TRACE("<-- %08x\n", hr);
return hr;
}
@ -6228,7 +6310,11 @@ static HRESULT TransactedSnapshotImpl_StreamSetSize(StorageBaseImpl *base,
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 @@ static HRESULT TransactedSnapshotImpl_StreamSetSize(StorageBaseImpl *base,
if (SUCCEEDED(hr))
This->entries[index].data.size = newsize;
TRACE("<-- %08x\n", hr);
return hr;
}
@ -6280,10 +6367,18 @@ static HRESULT TransactedSnapshotImpl_StreamLink(StorageBaseImpl *base,
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 @@ static HRESULT WINAPI TransactedSharedImpl_Commit(
This->lastTransactionSig = transactionSig+1;
}
}
TRACE("<-- %08x\n", hr);
return hr;
}
@ -9165,7 +9260,10 @@ static HRESULT STREAM_ReadString( IStream *stm, LPWSTR *string )
count = 0;
r = IStream_Read( stm, str, len, &count );
if( FAILED( r ) )
{
CoTaskMemFree( str );
return r;
}
if( count != len )
{
CoTaskMemFree( str );

View file

@ -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 @@ static inline HRESULT generate_ipid(struct stub_manager *m, IPID *ipid)
}
/* 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 @@ struct ifstub *stub_manager_new_ifstub(struct stub_manager *m, IRpcStubBuffer *s
stub->stubbuffer = sb;
if (sb) IRpcStubBuffer_AddRef(sb);
IUnknown_AddRef(iptr);
stub->iface = iptr;
stub->flags = flags;
stub->iid = *iid;
@ -102,7 +109,8 @@ static void stub_manager_delete_ifstub(struct stub_manager *m, struct ifstub *if
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 @@ struct ifstub *stub_manager_find_ifstub(struct stub_manager *m, REFIID iid, MSHL
/* 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 @@ struct stub_manager *new_stub_manager(APARTMENT *apt, IUnknown *object)
* 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 @@ struct stub_manager *new_stub_manager(APARTMENT *apt, IUnknown *object)
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 @@ static void stub_manager_delete(struct stub_manager *m)
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 @@ ULONG stub_manager_int_release(struct stub_manager *This)
/* 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 @@ struct stub_manager *get_stub_manager_from_object(APARTMENT *apt, void *object)
}
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);
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);
IUnknown_Release(object);
return result;
}
/* gets the stub manager associated with an object id - caller must have
@ -486,6 +509,7 @@ static HRESULT ipid_to_stub_manager(const IPID *ipid, APARTMENT **stub_apt, stru
* 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 @@ HRESULT ipid_get_dispatch_params(const IPID *ipid, APARTMENT **stub_apt,
*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 @@ static HRESULT WINAPI RemUnknown_QueryInterface(IRemUnknown *iface, REFIID riid,
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;

View file

@ -1472,6 +1472,7 @@ unsigned char * WINAPI WdtpInterfacePointer_UserUnmarshal(ULONG *pFlags, unsigne
IStream *stm;
DWORD size;
void *ptr;
IUnknown *orig;
TRACE("(%s, %p, %p, %s)\n", debugstr_user_flags(pFlags), pBuffer, ppunk, debugstr_guid(riid));
@ -1499,11 +1500,14 @@ unsigned char * WINAPI WdtpInterfacePointer_UserUnmarshal(ULONG *pFlags, unsigne
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 @@ unsigned char * __RPC_USER STGMEDIUM_UserUnmarshal(ULONG *pFlags, unsigned char
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 @@ unsigned char * __RPC_USER STGMEDIUM_UserUnmarshal(ULONG *pFlags, unsigned char
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 @@ unsigned char * __RPC_USER STGMEDIUM_UserUnmarshal(ULONG *pFlags, unsigned char
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 @@ HRESULT __RPC_STUB IDataObject_GetData_Stub(
return IDataObject_GetData(This, pformatetcIn, pRemoteMedium);
}
HRESULT CALLBACK IDataObject_GetDataHere_Proxy(
IDataObject* This,
FORMATETC *pformatetc,
STGMEDIUM *pmedium)
HRESULT CALLBACK IDataObject_GetDataHere_Proxy(IDataObject *iface, FORMATETC *fmt, STGMEDIUM *med)
{
TRACE("(%p)->(%p, %p)\n", This, pformatetc, pmedium);
return IDataObject_RemoteGetDataHere_Proxy(This, pformatetc, pmedium);
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(

View file

@ -144,7 +144,7 @@ reactos/dll/win32/ntprint # Synced to WineStaging-1.7.47
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