mirror of
https://github.com/reactos/reactos.git
synced 2024-06-30 09:50:07 +00:00
[OLE32] Sync with Wine Staging 1.7.55. CORE-10536
svn path=/trunk/; revision=69908
This commit is contained in:
parent
ca6b297569
commit
40c6100667
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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))
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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.@]
|
||||
*
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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, ¶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 @@ 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);
|
||||
}
|
||||
|
|
|
@ -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, ¤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 @@ 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 );
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue