mirror of
https://github.com/reactos/reactos.git
synced 2025-08-04 06:16:38 +00:00
[OLE32] Sync with Wine Staging 3.9. CORE-14656
This commit is contained in:
parent
9ce306e4cc
commit
85037eb745
8 changed files with 327 additions and 196 deletions
|
@ -723,6 +723,36 @@ static inline BOOL apartment_is_model(const APARTMENT *apt, DWORD model)
|
|||
return (apt->multi_threaded == !(model & COINIT_APARTMENTTHREADED));
|
||||
}
|
||||
|
||||
/* gets the multi-threaded apartment if it exists. The caller must
|
||||
* release the reference from the apartment as soon as the apartment pointer
|
||||
* is no longer required. */
|
||||
static APARTMENT *apartment_find_mta(void)
|
||||
{
|
||||
APARTMENT *apt;
|
||||
|
||||
EnterCriticalSection(&csApartment);
|
||||
|
||||
if ((apt = MTA))
|
||||
apartment_addref(apt);
|
||||
|
||||
LeaveCriticalSection(&csApartment);
|
||||
|
||||
return apt;
|
||||
}
|
||||
|
||||
/* Return the current apartment if it exists, or, failing that, the MTA. Caller
|
||||
* must free the returned apartment in either case. */
|
||||
APARTMENT *apartment_get_current_or_mta(void)
|
||||
{
|
||||
APARTMENT *apt = COM_CurrentApt();
|
||||
if (apt)
|
||||
{
|
||||
apartment_addref(apt);
|
||||
return apt;
|
||||
}
|
||||
return apartment_find_mta();
|
||||
}
|
||||
|
||||
static void COM_RevokeRegisteredClassObject(RegisteredClass *curClass)
|
||||
{
|
||||
list_remove(&curClass->entry);
|
||||
|
@ -1065,8 +1095,7 @@ HRESULT WINAPI DECLSPEC_HOTPATCH CoRevokeClassObject(
|
|||
|
||||
TRACE("(%08x)\n",dwRegister);
|
||||
|
||||
apt = COM_CurrentApt();
|
||||
if (!apt)
|
||||
if (!(apt = apartment_get_current_or_mta()))
|
||||
{
|
||||
ERR("COM was not initialized\n");
|
||||
return CO_E_NOTINITIALIZED;
|
||||
|
@ -1097,7 +1126,7 @@ HRESULT WINAPI DECLSPEC_HOTPATCH CoRevokeClassObject(
|
|||
}
|
||||
|
||||
LeaveCriticalSection( &csRegisteredClassList );
|
||||
|
||||
apartment_release(apt);
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
@ -1151,9 +1180,17 @@ DWORD apartment_release(struct apartment *apt)
|
|||
|
||||
ret = InterlockedDecrement(&apt->refs);
|
||||
TRACE("%s: after = %d\n", wine_dbgstr_longlong(apt->oxid), ret);
|
||||
|
||||
if (apt->being_destroyed)
|
||||
{
|
||||
LeaveCriticalSection(&csApartment);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* destruction stuff that needs to happen under csApartment CS */
|
||||
if (ret == 0)
|
||||
{
|
||||
apt->being_destroyed = TRUE;
|
||||
if (apt == MTA) MTA = NULL;
|
||||
else if (apt == MainApartment) MainApartment = NULL;
|
||||
list_remove(&apt->entry);
|
||||
|
@ -1301,31 +1338,6 @@ static APARTMENT *apartment_findmain(void)
|
|||
return result;
|
||||
}
|
||||
|
||||
/* gets the multi-threaded apartment if it exists. The caller must
|
||||
* release the reference from the apartment as soon as the apartment pointer
|
||||
* is no longer required. */
|
||||
static APARTMENT *apartment_find_multi_threaded(void)
|
||||
{
|
||||
APARTMENT *result = NULL;
|
||||
struct list *cursor;
|
||||
|
||||
EnterCriticalSection(&csApartment);
|
||||
|
||||
LIST_FOR_EACH( cursor, &apts )
|
||||
{
|
||||
struct apartment *apt = LIST_ENTRY( cursor, struct apartment, entry );
|
||||
if (apt->multi_threaded)
|
||||
{
|
||||
result = apt;
|
||||
apartment_addref(result);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&csApartment);
|
||||
return result;
|
||||
}
|
||||
|
||||
/* gets the specified class object by loading the appropriate DLL, if
|
||||
* necessary and calls the DllGetClassObject function for the DLL */
|
||||
static HRESULT apartment_getclassobject(struct apartment *apt, LPCWSTR dllpath,
|
||||
|
@ -1345,7 +1357,7 @@ static HRESULT apartment_getclassobject(struct apartment *apt, LPCWSTR dllpath,
|
|||
hr = DllGetClassObject(rclsid, riid, ppv);
|
||||
|
||||
if (hr != S_OK)
|
||||
ERR("DllGetClassObject returned error 0x%08x\n", hr);
|
||||
ERR("DllGetClassObject returned error 0x%08x for dll %s\n", hr, debugstr_w(dllpath));
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
@ -1394,7 +1406,7 @@ static HRESULT apartment_getclassobject(struct apartment *apt, LPCWSTR dllpath,
|
|||
hr = apartment_loaded_dll->dll->DllGetClassObject(rclsid, riid, ppv);
|
||||
|
||||
if (hr != S_OK)
|
||||
ERR("DllGetClassObject returned error 0x%08x\n", hr);
|
||||
ERR("DllGetClassObject returned error 0x%08x for dll %s\n", hr, debugstr_w(dllpath));
|
||||
}
|
||||
|
||||
return hr;
|
||||
|
@ -2065,9 +2077,11 @@ HRESULT WINAPI CoDisconnectObject( LPUNKNOWN lpUnk, DWORD reserved )
|
|||
return hr;
|
||||
}
|
||||
|
||||
apt = COM_CurrentApt();
|
||||
if (!apt)
|
||||
if (!(apt = apartment_get_current_or_mta()))
|
||||
{
|
||||
ERR("apartment not initialised\n");
|
||||
return CO_E_NOTINITIALIZED;
|
||||
}
|
||||
|
||||
manager = get_stub_manager_from_object(apt, lpUnk, FALSE);
|
||||
if (manager) {
|
||||
|
@ -2082,6 +2096,7 @@ HRESULT WINAPI CoDisconnectObject( LPUNKNOWN lpUnk, DWORD reserved )
|
|||
* not found, making apps think that the object was disconnected, when
|
||||
* it actually wasn't */
|
||||
|
||||
apartment_release(apt);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -2589,7 +2604,7 @@ HRESULT WINAPI CoGetPSClsid(REFIID riid, CLSID *pclsid)
|
|||
static const WCHAR wszInterface[] = {'I','n','t','e','r','f','a','c','e','\\',0};
|
||||
static const WCHAR wszPSC[] = {'\\','P','r','o','x','y','S','t','u','b','C','l','s','i','d','3','2',0};
|
||||
WCHAR path[ARRAYSIZE(wszInterface) - 1 + CHARS_IN_GUID - 1 + ARRAYSIZE(wszPSC)];
|
||||
APARTMENT *apt = COM_CurrentApt();
|
||||
APARTMENT *apt;
|
||||
struct registered_psclsid *registered_psclsid;
|
||||
ACTCTX_SECTION_KEYED_DATA data;
|
||||
HRESULT hr;
|
||||
|
@ -2598,11 +2613,12 @@ HRESULT WINAPI CoGetPSClsid(REFIID riid, CLSID *pclsid)
|
|||
|
||||
TRACE("() riid=%s, pclsid=%p\n", debugstr_guid(riid), pclsid);
|
||||
|
||||
if (!apt)
|
||||
if (!(apt = apartment_get_current_or_mta()))
|
||||
{
|
||||
ERR("apartment not initialised\n");
|
||||
return CO_E_NOTINITIALIZED;
|
||||
}
|
||||
apartment_release(apt);
|
||||
|
||||
if (!pclsid)
|
||||
return E_INVALIDARG;
|
||||
|
@ -2673,16 +2689,17 @@ HRESULT WINAPI CoGetPSClsid(REFIID riid, CLSID *pclsid)
|
|||
*/
|
||||
HRESULT WINAPI CoRegisterPSClsid(REFIID riid, REFCLSID rclsid)
|
||||
{
|
||||
APARTMENT *apt = COM_CurrentApt();
|
||||
APARTMENT *apt;
|
||||
struct registered_psclsid *registered_psclsid;
|
||||
|
||||
TRACE("(%s, %s)\n", debugstr_guid(riid), debugstr_guid(rclsid));
|
||||
|
||||
if (!apt)
|
||||
if (!(apt = apartment_get_current_or_mta()))
|
||||
{
|
||||
ERR("apartment not initialised\n");
|
||||
return CO_E_NOTINITIALIZED;
|
||||
}
|
||||
apartment_release(apt);
|
||||
|
||||
EnterCriticalSection(&cs_registered_psclsid_list);
|
||||
|
||||
|
@ -2808,8 +2825,7 @@ HRESULT WINAPI CoRegisterClassObject(
|
|||
if ( (lpdwRegister==0) || (pUnk==0) )
|
||||
return E_INVALIDARG;
|
||||
|
||||
apt = COM_CurrentApt();
|
||||
if (!apt)
|
||||
if (!(apt = apartment_get_current_or_mta()))
|
||||
{
|
||||
ERR("COM was not initialized\n");
|
||||
return CO_E_NOTINITIALIZED;
|
||||
|
@ -2832,16 +2848,21 @@ HRESULT WINAPI CoRegisterClassObject(
|
|||
if (dwClsContext & CLSCTX_LOCAL_SERVER)
|
||||
hr = CoLockObjectExternal(foundObject, TRUE, FALSE);
|
||||
IUnknown_Release(foundObject);
|
||||
apartment_release(apt);
|
||||
return hr;
|
||||
}
|
||||
IUnknown_Release(foundObject);
|
||||
ERR("object already registered for class %s\n", debugstr_guid(rclsid));
|
||||
apartment_release(apt);
|
||||
return CO_E_OBJISREG;
|
||||
}
|
||||
|
||||
newClass = HeapAlloc(GetProcessHeap(), 0, sizeof(RegisteredClass));
|
||||
if ( newClass == NULL )
|
||||
{
|
||||
apartment_release(apt);
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
newClass->classIdentifier = *rclsid;
|
||||
newClass->apartment_id = apt->oxid;
|
||||
|
@ -2870,7 +2891,10 @@ HRESULT WINAPI CoRegisterClassObject(
|
|||
|
||||
hr = get_local_server_stream(apt, &marshal_stream);
|
||||
if(FAILED(hr))
|
||||
{
|
||||
apartment_release(apt);
|
||||
return hr;
|
||||
}
|
||||
|
||||
hr = RPC_StartLocalServer(&newClass->classIdentifier,
|
||||
marshal_stream,
|
||||
|
@ -2878,6 +2902,7 @@ HRESULT WINAPI CoRegisterClassObject(
|
|||
&newClass->RpcRegistration);
|
||||
IStream_Release(marshal_stream);
|
||||
}
|
||||
apartment_release(apt);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -2995,7 +3020,6 @@ HRESULT WINAPI DECLSPEC_HOTPATCH CoGetClassObject(
|
|||
IUnknown *regClassObject;
|
||||
HRESULT hres = E_UNEXPECTED;
|
||||
APARTMENT *apt;
|
||||
BOOL release_apt = FALSE;
|
||||
|
||||
TRACE("CLSID: %s,IID: %s\n", debugstr_guid(rclsid), debugstr_guid(iid));
|
||||
|
||||
|
@ -3004,14 +3028,10 @@ HRESULT WINAPI DECLSPEC_HOTPATCH CoGetClassObject(
|
|||
|
||||
*ppv = NULL;
|
||||
|
||||
if (!(apt = COM_CurrentApt()))
|
||||
if (!(apt = apartment_get_current_or_mta()))
|
||||
{
|
||||
if (!(apt = apartment_find_multi_threaded()))
|
||||
{
|
||||
ERR("apartment not initialised\n");
|
||||
return CO_E_NOTINITIALIZED;
|
||||
}
|
||||
release_apt = TRUE;
|
||||
ERR("apartment not initialised\n");
|
||||
return CO_E_NOTINITIALIZED;
|
||||
}
|
||||
|
||||
if (pServerInfo) {
|
||||
|
@ -3023,7 +3043,7 @@ HRESULT WINAPI DECLSPEC_HOTPATCH CoGetClassObject(
|
|||
{
|
||||
if (IsEqualCLSID(rclsid, &CLSID_InProcFreeMarshaler))
|
||||
{
|
||||
if (release_apt) apartment_release(apt);
|
||||
apartment_release(apt);
|
||||
return FTMarshalCF_Create(iid, ppv);
|
||||
}
|
||||
if (IsEqualCLSID(rclsid, &CLSID_GlobalOptions))
|
||||
|
@ -3049,7 +3069,7 @@ HRESULT WINAPI DECLSPEC_HOTPATCH CoGetClassObject(
|
|||
|
||||
hres = get_inproc_class_object(apt, &clsreg, &comclass->clsid, iid, !(dwClsContext & WINE_CLSCTX_DONT_HOST), ppv);
|
||||
ReleaseActCtx(data.hActCtx);
|
||||
if (release_apt) apartment_release(apt);
|
||||
apartment_release(apt);
|
||||
return hres;
|
||||
}
|
||||
}
|
||||
|
@ -3070,7 +3090,7 @@ HRESULT WINAPI DECLSPEC_HOTPATCH CoGetClassObject(
|
|||
* is good since we are not returning it in the "out" parameter.
|
||||
*/
|
||||
IUnknown_Release(regClassObject);
|
||||
if (release_apt) apartment_release(apt);
|
||||
apartment_release(apt);
|
||||
return hres;
|
||||
}
|
||||
|
||||
|
@ -3105,7 +3125,7 @@ HRESULT WINAPI DECLSPEC_HOTPATCH CoGetClassObject(
|
|||
* other types */
|
||||
if (SUCCEEDED(hres))
|
||||
{
|
||||
if (release_apt) apartment_release(apt);
|
||||
apartment_release(apt);
|
||||
return hres;
|
||||
}
|
||||
}
|
||||
|
@ -3141,11 +3161,11 @@ HRESULT WINAPI DECLSPEC_HOTPATCH CoGetClassObject(
|
|||
* other types */
|
||||
if (SUCCEEDED(hres))
|
||||
{
|
||||
if (release_apt) apartment_release(apt);
|
||||
apartment_release(apt);
|
||||
return hres;
|
||||
}
|
||||
}
|
||||
if (release_apt) apartment_release(apt);
|
||||
apartment_release(apt);
|
||||
|
||||
/* Next try out of process */
|
||||
if (CLSCTX_LOCAL_SERVER & dwClsContext)
|
||||
|
@ -3304,15 +3324,12 @@ HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstanceEx(
|
|||
if(FAILED(hres))
|
||||
clsid = *rclsid;
|
||||
|
||||
if (!(apt = COM_CurrentApt()))
|
||||
if (!(apt = apartment_get_current_or_mta()))
|
||||
{
|
||||
if (!(apt = apartment_find_multi_threaded()))
|
||||
{
|
||||
ERR("apartment not initialised\n");
|
||||
return CO_E_NOTINITIALIZED;
|
||||
}
|
||||
apartment_release(apt);
|
||||
ERR("apartment not initialised\n");
|
||||
return CO_E_NOTINITIALIZED;
|
||||
}
|
||||
apartment_release(apt);
|
||||
|
||||
/*
|
||||
* The Standard Global Interface Table (GIT) object is a process-wide singleton.
|
||||
|
@ -3646,8 +3663,11 @@ HRESULT WINAPI CoLockObjectExternal(
|
|||
TRACE("pUnk=%p, fLock=%s, fLastUnlockReleases=%s\n",
|
||||
pUnk, fLock ? "TRUE" : "FALSE", fLastUnlockReleases ? "TRUE" : "FALSE");
|
||||
|
||||
apt = COM_CurrentApt();
|
||||
if (!apt) return CO_E_NOTINITIALIZED;
|
||||
if (!(apt = apartment_get_current_or_mta()))
|
||||
{
|
||||
ERR("apartment not initialised\n");
|
||||
return CO_E_NOTINITIALIZED;
|
||||
}
|
||||
|
||||
stubmgr = get_stub_manager_from_object(apt, pUnk, fLock);
|
||||
if (!stubmgr)
|
||||
|
@ -3656,6 +3676,7 @@ HRESULT WINAPI CoLockObjectExternal(
|
|||
/* Note: native is pretty broken here because it just silently
|
||||
* fails, without returning an appropriate error code, making apps
|
||||
* think that the object was disconnected, when it actually wasn't */
|
||||
apartment_release(apt);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -3665,6 +3686,7 @@ HRESULT WINAPI CoLockObjectExternal(
|
|||
stub_manager_ext_release(stubmgr, 1, FALSE, fLastUnlockReleases);
|
||||
|
||||
stub_manager_int_release(stubmgr);
|
||||
apartment_release(apt);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -5004,22 +5026,19 @@ HRESULT WINAPI CoGetObjectContext(REFIID riid, void **ppv)
|
|||
HRESULT WINAPI CoGetContextToken( ULONG_PTR *token )
|
||||
{
|
||||
struct oletls *info = COM_CurrentInfo();
|
||||
APARTMENT *apt;
|
||||
|
||||
TRACE("(%p)\n", token);
|
||||
|
||||
if (!info)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
if (!info->apt)
|
||||
if (!(apt = apartment_get_current_or_mta()))
|
||||
{
|
||||
APARTMENT *apt;
|
||||
if (!(apt = apartment_find_multi_threaded()))
|
||||
{
|
||||
ERR("apartment not initialised\n");
|
||||
return CO_E_NOTINITIALIZED;
|
||||
}
|
||||
apartment_release(apt);
|
||||
ERR("apartment not initialised\n");
|
||||
return CO_E_NOTINITIALIZED;
|
||||
}
|
||||
apartment_release(apt);
|
||||
|
||||
if (!token)
|
||||
return E_POINTER;
|
||||
|
@ -5095,8 +5114,9 @@ HRESULT Handler_DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
|
|||
HRESULT WINAPI CoGetApartmentType(APTTYPE *type, APTTYPEQUALIFIER *qualifier)
|
||||
{
|
||||
struct oletls *info = COM_CurrentInfo();
|
||||
APARTMENT *apt;
|
||||
|
||||
FIXME("(%p, %p): semi-stub\n", type, qualifier);
|
||||
TRACE("(%p, %p)\n", type, qualifier);
|
||||
|
||||
if (!type || !qualifier)
|
||||
return E_INVALIDARG;
|
||||
|
@ -5115,6 +5135,13 @@ HRESULT WINAPI CoGetApartmentType(APTTYPE *type, APTTYPEQUALIFIER *qualifier)
|
|||
|
||||
*qualifier = APTTYPEQUALIFIER_NONE;
|
||||
|
||||
if (!info->apt && (apt = apartment_find_mta()))
|
||||
{
|
||||
apartment_release(apt);
|
||||
*type = APTTYPE_MTA;
|
||||
*qualifier = APTTYPEQUALIFIER_IMPLICIT_MTA;
|
||||
}
|
||||
|
||||
return info->apt ? S_OK : CO_E_NOTINITIALIZED;
|
||||
}
|
||||
|
||||
|
|
|
@ -142,6 +142,7 @@ struct apartment
|
|||
DWORD host_apt_tid; /* thread ID of apartment hosting objects of differing threading model (CS cs) */
|
||||
HWND host_apt_hwnd; /* handle to apartment window of host apartment (CS cs) */
|
||||
LocalServer *local_server; /* A marshallable object exposing local servers (CS cs) */
|
||||
BOOL being_destroyed; /* is currently being destroyed */
|
||||
|
||||
/* FIXME: OIDs should be given out by RPCSS */
|
||||
OID oidc; /* object ID counter, starts at 1, zero is invalid OID (CS cs) */
|
||||
|
@ -199,7 +200,7 @@ void stub_manager_release_marshal_data(struct stub_manager *m, ULONG refs, const
|
|||
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 start_apartment_remote_unknown(APARTMENT *apt) DECLSPEC_HIDDEN;
|
||||
|
||||
HRESULT marshal_object(APARTMENT *apt, STDOBJREF *stdobjref, REFIID riid, IUnknown *obj, DWORD dest_context, void *dest_context_data, MSHLFLAGS mshlflags) DECLSPEC_HIDDEN;
|
||||
|
||||
|
@ -211,7 +212,7 @@ void RPC_StartRemoting(struct apartment *apt) DECLSPEC_HIDDEN;
|
|||
HRESULT RPC_CreateClientChannel(const OXID *oxid, const IPID *ipid,
|
||||
const OXID_INFO *oxid_info,
|
||||
DWORD dest_context, void *dest_context_data,
|
||||
IRpcChannelBuffer **chan) DECLSPEC_HIDDEN;
|
||||
IRpcChannelBuffer **chan, APARTMENT *apt) DECLSPEC_HIDDEN;
|
||||
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;
|
||||
|
@ -247,6 +248,7 @@ HRESULT apartment_createwindowifneeded(struct apartment *apt) DECLSPEC_HIDDEN;
|
|||
HWND apartment_getwindow(const struct apartment *apt) DECLSPEC_HIDDEN;
|
||||
HRESULT enter_apartment(struct oletls *info, DWORD model) DECLSPEC_HIDDEN;
|
||||
void leave_apartment(struct oletls *info) DECLSPEC_HIDDEN;
|
||||
APARTMENT *apartment_get_current_or_mta(void) DECLSPEC_HIDDEN;
|
||||
|
||||
/* DCOM messages used by the apartment window (not compatible with native) */
|
||||
#define DM_EXECUTERPC (WM_USER + 0) /* WPARAM = 0, LPARAM = (struct dispatch_params *) */
|
||||
|
|
|
@ -547,6 +547,41 @@ static HRESULT open_pres_stream( IStorage *stg, int stream_number, IStream **stm
|
|||
return IStorage_OpenStream( stg, name, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, stm );
|
||||
}
|
||||
|
||||
static HRESULT synthesize_emf( HMETAFILEPICT data, STGMEDIUM *med )
|
||||
{
|
||||
METAFILEPICT *pict;
|
||||
HRESULT hr = E_FAIL;
|
||||
UINT size;
|
||||
void *bits;
|
||||
|
||||
if (!(pict = GlobalLock( data ))) return hr;
|
||||
|
||||
size = GetMetaFileBitsEx( pict->hMF, 0, NULL );
|
||||
if ((bits = HeapAlloc( GetProcessHeap(), 0, size )))
|
||||
{
|
||||
GetMetaFileBitsEx( pict->hMF, size, bits );
|
||||
med->u.hEnhMetaFile = SetWinMetaFileBits( size, bits, NULL, pict );
|
||||
HeapFree( GetProcessHeap(), 0, bits );
|
||||
med->tymed = TYMED_ENHMF;
|
||||
med->pUnkForRelease = NULL;
|
||||
hr = S_OK;
|
||||
}
|
||||
|
||||
GlobalUnlock( data );
|
||||
return hr;
|
||||
}
|
||||
#include <pshpack2.h>
|
||||
struct meta_placeable
|
||||
{
|
||||
DWORD key;
|
||||
WORD hwmf;
|
||||
WORD bounding_box[4];
|
||||
WORD inch;
|
||||
DWORD reserved;
|
||||
WORD checksum;
|
||||
};
|
||||
#include <poppack.h>
|
||||
|
||||
static HRESULT load_mf_pict( DataCacheEntry *cache_entry, IStream *stm )
|
||||
{
|
||||
HRESULT hr;
|
||||
|
@ -559,25 +594,26 @@ static HRESULT load_mf_pict( DataCacheEntry *cache_entry, IStream *stm )
|
|||
CLIPFORMAT clipformat;
|
||||
static const LARGE_INTEGER offset_zero;
|
||||
ULONG read;
|
||||
|
||||
if (cache_entry->load_stream_num == STREAM_NUMBER_CONTENTS)
|
||||
{
|
||||
FIXME( "Unimplemented for CONTENTS stream\n" );
|
||||
return E_FAIL;
|
||||
}
|
||||
struct meta_placeable mf_place;
|
||||
|
||||
hr = IStream_Stat( stm, &stat, STATFLAG_NONAME );
|
||||
if (FAILED( hr )) return hr;
|
||||
|
||||
hr = read_clipformat( stm, &clipformat );
|
||||
if (FAILED( hr )) return hr;
|
||||
|
||||
hr = IStream_Read( stm, &header, sizeof(header), &read );
|
||||
if (hr != S_OK || read != sizeof(header)) return E_FAIL;
|
||||
if (cache_entry->load_stream_num != STREAM_NUMBER_CONTENTS)
|
||||
{
|
||||
hr = read_clipformat( stm, &clipformat );
|
||||
if (hr != S_OK) return hr;
|
||||
hr = IStream_Read( stm, &header, sizeof(header), &read );
|
||||
if (hr != S_OK) return hr;
|
||||
}
|
||||
else
|
||||
{
|
||||
hr = IStream_Read( stm, &mf_place, sizeof(mf_place), &read );
|
||||
if (hr != S_OK) return hr;
|
||||
}
|
||||
|
||||
hr = IStream_Seek( stm, offset_zero, STREAM_SEEK_CUR, ¤t_pos );
|
||||
if (FAILED( hr )) return hr;
|
||||
|
||||
stat.cbSize.QuadPart -= current_pos.QuadPart;
|
||||
|
||||
hmfpict = GlobalAlloc( GMEM_MOVEABLE, sizeof(METAFILEPICT) );
|
||||
|
@ -592,14 +628,23 @@ static HRESULT load_mf_pict( DataCacheEntry *cache_entry, IStream *stm )
|
|||
}
|
||||
|
||||
hr = IStream_Read( stm, bits, stat.cbSize.u.LowPart, &read );
|
||||
if (hr != S_OK || read != stat.cbSize.u.LowPart) hr = E_FAIL;
|
||||
|
||||
if (SUCCEEDED( hr ))
|
||||
{
|
||||
/* FIXME: get this from the stream */
|
||||
mfpict->mm = MM_ANISOTROPIC;
|
||||
mfpict->xExt = header.dwObjectExtentX;
|
||||
mfpict->yExt = header.dwObjectExtentY;
|
||||
/* FIXME: get this from the stream */
|
||||
if (cache_entry->load_stream_num != STREAM_NUMBER_CONTENTS)
|
||||
{
|
||||
mfpict->xExt = header.dwObjectExtentX;
|
||||
mfpict->yExt = header.dwObjectExtentY;
|
||||
}
|
||||
else
|
||||
{
|
||||
mfpict->xExt = ((mf_place.bounding_box[2] - mf_place.bounding_box[0])
|
||||
* 2540) / mf_place.inch;
|
||||
mfpict->yExt = ((mf_place.bounding_box[3] - mf_place.bounding_box[1])
|
||||
* 2540) / mf_place.inch;
|
||||
}
|
||||
mfpict->hMF = SetMetaFileBitsEx( stat.cbSize.u.LowPart, bits );
|
||||
if (!mfpict->hMF)
|
||||
hr = E_FAIL;
|
||||
|
@ -623,48 +668,61 @@ static HRESULT load_dib( DataCacheEntry *cache_entry, IStream *stm )
|
|||
{
|
||||
HRESULT hr;
|
||||
STATSTG stat;
|
||||
void *dib;
|
||||
BYTE *dib;
|
||||
HGLOBAL hglobal;
|
||||
ULONG read, info_size, bi_size;
|
||||
BITMAPFILEHEADER file;
|
||||
BITMAPINFOHEADER *info;
|
||||
|
||||
if (cache_entry->load_stream_num != STREAM_NUMBER_CONTENTS)
|
||||
{
|
||||
FIXME( "Unimplemented for presentation stream\n" );
|
||||
return E_FAIL;
|
||||
}
|
||||
CLIPFORMAT cf;
|
||||
PresentationDataHeader pres;
|
||||
ULARGE_INTEGER current_pos;
|
||||
static const LARGE_INTEGER offset_zero;
|
||||
|
||||
hr = IStream_Stat( stm, &stat, STATFLAG_NONAME );
|
||||
if (FAILED( hr )) return hr;
|
||||
|
||||
if (stat.cbSize.QuadPart < sizeof(file) + sizeof(DWORD)) return E_FAIL;
|
||||
hr = IStream_Read( stm, &file, sizeof(file), &read );
|
||||
if (hr != S_OK || read != sizeof(file)) return E_FAIL;
|
||||
stat.cbSize.QuadPart -= sizeof(file);
|
||||
if (cache_entry->load_stream_num != STREAM_NUMBER_CONTENTS)
|
||||
{
|
||||
hr = read_clipformat( stm, &cf );
|
||||
if (hr != S_OK) return hr;
|
||||
hr = IStream_Read( stm, &pres, sizeof(pres), &read );
|
||||
if (hr != S_OK) return hr;
|
||||
}
|
||||
else
|
||||
{
|
||||
hr = IStream_Read( stm, &file, sizeof(BITMAPFILEHEADER), &read );
|
||||
if (hr != S_OK) return hr;
|
||||
}
|
||||
|
||||
hr = IStream_Seek( stm, offset_zero, STREAM_SEEK_CUR, ¤t_pos );
|
||||
if (FAILED( hr )) return hr;
|
||||
stat.cbSize.QuadPart -= current_pos.QuadPart;
|
||||
|
||||
hglobal = GlobalAlloc( GMEM_MOVEABLE, stat.cbSize.u.LowPart );
|
||||
if (!hglobal) return E_OUTOFMEMORY;
|
||||
dib = GlobalLock( hglobal );
|
||||
|
||||
/* read first DWORD of BITMAPINFOHEADER */
|
||||
hr = IStream_Read( stm, dib, sizeof(DWORD), &read );
|
||||
if (hr != S_OK || read != sizeof(DWORD)) goto fail;
|
||||
if (hr != S_OK) goto fail;
|
||||
bi_size = *(DWORD *)dib;
|
||||
if (stat.cbSize.QuadPart < bi_size) goto fail;
|
||||
|
||||
hr = IStream_Read( stm, (char *)dib + sizeof(DWORD), bi_size - sizeof(DWORD), &read );
|
||||
if (hr != S_OK || read != bi_size - sizeof(DWORD)) goto fail;
|
||||
/* read rest of BITMAPINFOHEADER */
|
||||
hr = IStream_Read( stm, dib + sizeof(DWORD), bi_size - sizeof(DWORD), &read );
|
||||
if (hr != S_OK) goto fail;
|
||||
|
||||
info_size = bitmap_info_size( dib, DIB_RGB_COLORS );
|
||||
info_size = bitmap_info_size( (BITMAPINFO *)dib, DIB_RGB_COLORS );
|
||||
if (stat.cbSize.QuadPart < info_size) goto fail;
|
||||
if (info_size > bi_size)
|
||||
{
|
||||
hr = IStream_Read( stm, (char *)dib + bi_size, info_size - bi_size, &read );
|
||||
if (hr != S_OK || read != info_size - bi_size) goto fail;
|
||||
hr = IStream_Read( stm, dib + bi_size, info_size - bi_size, &read );
|
||||
if (hr != S_OK) goto fail;
|
||||
}
|
||||
stat.cbSize.QuadPart -= info_size;
|
||||
|
||||
if (file.bfOffBits)
|
||||
/* set Stream pointer to beginning of bitmap bits */
|
||||
if (cache_entry->load_stream_num == STREAM_NUMBER_CONTENTS && file.bfOffBits)
|
||||
{
|
||||
LARGE_INTEGER skip;
|
||||
|
||||
|
@ -675,8 +733,8 @@ static HRESULT load_dib( DataCacheEntry *cache_entry, IStream *stm )
|
|||
stat.cbSize.QuadPart -= skip.QuadPart;
|
||||
}
|
||||
|
||||
hr = IStream_Read( stm, (char *)dib + info_size, stat.cbSize.u.LowPart, &read );
|
||||
if (hr != S_OK || read != stat.cbSize.QuadPart) goto fail;
|
||||
hr = IStream_Read( stm, dib + info_size, stat.cbSize.u.LowPart, &read );
|
||||
if (hr != S_OK) goto fail;
|
||||
|
||||
if (bi_size >= sizeof(*info))
|
||||
{
|
||||
|
@ -695,15 +753,69 @@ static HRESULT load_dib( DataCacheEntry *cache_entry, IStream *stm )
|
|||
cache_entry->stgmedium.tymed = TYMED_HGLOBAL;
|
||||
cache_entry->stgmedium.u.hGlobal = hglobal;
|
||||
|
||||
return S_OK;
|
||||
return hr;
|
||||
|
||||
fail:
|
||||
GlobalUnlock( hglobal );
|
||||
GlobalFree( hglobal );
|
||||
return E_FAIL;
|
||||
return hr;
|
||||
|
||||
}
|
||||
|
||||
static HRESULT load_emf( DataCacheEntry *cache_entry, IStream *stm )
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (cache_entry->load_stream_num != STREAM_NUMBER_CONTENTS)
|
||||
{
|
||||
STGMEDIUM stgmed;
|
||||
|
||||
hr = load_mf_pict( cache_entry, stm );
|
||||
if (SUCCEEDED( hr ))
|
||||
{
|
||||
hr = synthesize_emf( cache_entry->stgmedium.u.hMetaFilePict, &stgmed );
|
||||
ReleaseStgMedium( &cache_entry->stgmedium );
|
||||
}
|
||||
if (SUCCEEDED( hr ))
|
||||
cache_entry->stgmedium = stgmed;
|
||||
}
|
||||
else
|
||||
{
|
||||
STATSTG stat;
|
||||
BYTE *data;
|
||||
ULONG read, size_bits;
|
||||
|
||||
hr = IStream_Stat( stm, &stat, STATFLAG_NONAME );
|
||||
|
||||
if (SUCCEEDED( hr ))
|
||||
{
|
||||
data = HeapAlloc( GetProcessHeap(), 0, stat.cbSize.u.LowPart );
|
||||
if (!data) return E_OUTOFMEMORY;
|
||||
|
||||
hr = IStream_Read( stm, data, stat.cbSize.u.LowPart, &read );
|
||||
if (hr != S_OK)
|
||||
{
|
||||
HeapFree( GetProcessHeap(), 0, data );
|
||||
return hr;
|
||||
}
|
||||
|
||||
if (read <= sizeof(DWORD) + sizeof(ENHMETAHEADER))
|
||||
{
|
||||
HeapFree( GetProcessHeap(), 0, data );
|
||||
return E_FAIL;
|
||||
}
|
||||
size_bits = read - sizeof(DWORD) - sizeof(ENHMETAHEADER);
|
||||
cache_entry->stgmedium.u.hEnhMetaFile = SetEnhMetaFileBits( size_bits, data + (read - size_bits) );
|
||||
cache_entry->stgmedium.tymed = TYMED_ENHMF;
|
||||
cache_entry->stgmedium.pUnkForRelease = NULL;
|
||||
|
||||
HeapFree( GetProcessHeap(), 0, data );
|
||||
}
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* DataCacheEntry_LoadData
|
||||
*
|
||||
|
@ -736,6 +848,10 @@ static HRESULT DataCacheEntry_LoadData(DataCacheEntry *cache_entry, IStorage *st
|
|||
hr = load_dib( cache_entry, stm );
|
||||
break;
|
||||
|
||||
case CF_ENHMETAFILE:
|
||||
hr = load_emf( cache_entry, stm );
|
||||
break;
|
||||
|
||||
default:
|
||||
FIXME( "Unimplemented clip format %x\n", cache_entry->fmtetc.cfFormat );
|
||||
hr = E_NOTIMPL;
|
||||
|
@ -817,18 +933,6 @@ end:
|
|||
return hr;
|
||||
}
|
||||
|
||||
#include <pshpack2.h>
|
||||
struct meta_placeable
|
||||
{
|
||||
DWORD key;
|
||||
WORD hwmf;
|
||||
WORD bounding_box[4];
|
||||
WORD inch;
|
||||
DWORD reserved;
|
||||
WORD checksum;
|
||||
};
|
||||
#include <poppack.h>
|
||||
|
||||
static HRESULT save_mfpict(DataCacheEntry *entry, BOOL contents, IStream *stream)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
|
@ -1118,30 +1222,6 @@ static HRESULT synthesize_bitmap( HGLOBAL dib, STGMEDIUM *med )
|
|||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT synthesize_emf( HMETAFILEPICT data, STGMEDIUM *med )
|
||||
{
|
||||
METAFILEPICT *pict;
|
||||
HRESULT hr = E_FAIL;
|
||||
UINT size;
|
||||
void *bits;
|
||||
|
||||
if (!(pict = GlobalLock( data ))) return hr;
|
||||
|
||||
size = GetMetaFileBitsEx( pict->hMF, 0, NULL );
|
||||
if ((bits = HeapAlloc( GetProcessHeap(), 0, size )))
|
||||
{
|
||||
GetMetaFileBitsEx( pict->hMF, size, bits );
|
||||
med->u.hEnhMetaFile = SetWinMetaFileBits( size, bits, NULL, pict );
|
||||
HeapFree( GetProcessHeap(), 0, bits );
|
||||
med->tymed = TYMED_ENHMF;
|
||||
med->pUnkForRelease = NULL;
|
||||
hr = S_OK;
|
||||
}
|
||||
|
||||
GlobalUnlock( data );
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT DataCacheEntry_SetData(DataCacheEntry *cache_entry,
|
||||
const FORMATETC *formatetc,
|
||||
STGMEDIUM *stgmedium,
|
||||
|
@ -1763,6 +1843,7 @@ static HRESULT WINAPI DataCache_Load( IPersistStorage *iface, IStorage *stg )
|
|||
|
||||
LIST_FOR_EACH_ENTRY_SAFE( entry, cursor2, &This->cache_list, DataCacheEntry, entry )
|
||||
DataCacheEntry_Destroy( This, entry );
|
||||
This->clsid = CLSID_NULL;
|
||||
|
||||
ReadClassStg( stg, &clsid );
|
||||
hr = create_automatic_entry( This, &clsid );
|
||||
|
|
|
@ -313,13 +313,15 @@ static HRESULT WINAPI ClientIdentity_QueryMultipleInterfaces(IMultiQI *iface, UL
|
|||
* the interfaces were returned */
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
APARTMENT *apt = apartment_get_current_or_mta();
|
||||
|
||||
/* try to unmarshal each object returned to us */
|
||||
for (i = 0; i < nonlocal_mqis; i++)
|
||||
{
|
||||
ULONG index = mapping[i];
|
||||
HRESULT hrobj = qiresults[i].hResult;
|
||||
if (hrobj == S_OK)
|
||||
hrobj = unmarshal_object(&qiresults[i].std, COM_CurrentApt(),
|
||||
hrobj = unmarshal_object(&qiresults[i].std, apt,
|
||||
This->dest_context,
|
||||
This->dest_context_data,
|
||||
pMQIs[index].pIID, &This->oxid_info,
|
||||
|
@ -331,6 +333,8 @@ static HRESULT WINAPI ClientIdentity_QueryMultipleInterfaces(IMultiQI *iface, UL
|
|||
ERR("Failed to get pointer to interface %s\n", debugstr_guid(pMQIs[index].pIID));
|
||||
pMQIs[index].hr = hrobj;
|
||||
}
|
||||
|
||||
apartment_release(apt);
|
||||
}
|
||||
|
||||
/* free the memory allocated by the proxy */
|
||||
|
@ -1010,8 +1014,7 @@ static HRESULT proxy_manager_get_remunknown(struct proxy_manager * This, IRemUnk
|
|||
if (This->sorflags & SORFP_NOLIFETIMEMGMT)
|
||||
return S_FALSE;
|
||||
|
||||
apt = COM_CurrentApt();
|
||||
if (!apt)
|
||||
if (!(apt = apartment_get_current_or_mta()))
|
||||
return CO_E_NOTINITIALIZED;
|
||||
|
||||
called_in_original_apt = This->parent && (This->parent->oxid == apt->oxid);
|
||||
|
@ -1046,7 +1049,7 @@ static HRESULT proxy_manager_get_remunknown(struct proxy_manager * This, IRemUnk
|
|||
stdobjref.ipid = This->oxid_info.ipidRemUnknown;
|
||||
|
||||
/* do the unmarshal */
|
||||
hr = unmarshal_object(&stdobjref, COM_CurrentApt(), This->dest_context,
|
||||
hr = unmarshal_object(&stdobjref, apt, This->dest_context,
|
||||
This->dest_context_data, &IID_IRemUnknown,
|
||||
&This->oxid_info, (void**)remunk);
|
||||
if (hr == S_OK && called_in_original_apt)
|
||||
|
@ -1056,6 +1059,7 @@ static HRESULT proxy_manager_get_remunknown(struct proxy_manager * This, IRemUnk
|
|||
}
|
||||
}
|
||||
LeaveCriticalSection(&This->cs);
|
||||
apartment_release(apt);
|
||||
|
||||
TRACE("got IRemUnknown* pointer %p, hr = 0x%08x\n", *remunk, hr);
|
||||
|
||||
|
@ -1221,11 +1225,11 @@ StdMarshalImpl_MarshalInterface(
|
|||
STDOBJREF stdobjref;
|
||||
ULONG res;
|
||||
HRESULT hres;
|
||||
APARTMENT *apt = COM_CurrentApt();
|
||||
APARTMENT *apt;
|
||||
|
||||
TRACE("(...,%s,...)\n", debugstr_guid(riid));
|
||||
|
||||
if (!apt)
|
||||
if (!(apt = apartment_get_current_or_mta()))
|
||||
{
|
||||
ERR("Apartment not initialized\n");
|
||||
return CO_E_NOTINITIALIZED;
|
||||
|
@ -1235,6 +1239,7 @@ StdMarshalImpl_MarshalInterface(
|
|||
RPC_StartRemoting(apt);
|
||||
|
||||
hres = marshal_object(apt, &stdobjref, riid, pv, dest_context, dest_context_data, mshlflags);
|
||||
apartment_release(apt);
|
||||
if (hres != S_OK)
|
||||
{
|
||||
ERR("Failed to create ifstub, hres=0x%x\n", hres);
|
||||
|
@ -1288,7 +1293,7 @@ static HRESULT unmarshal_object(const STDOBJREF *stdobjref, APARTMENT *apt,
|
|||
&proxy_manager->oxid_info,
|
||||
proxy_manager->dest_context,
|
||||
proxy_manager->dest_context_data,
|
||||
&chanbuf);
|
||||
&chanbuf, apt);
|
||||
if (hr == S_OK)
|
||||
hr = proxy_manager_create_ifproxy(proxy_manager, stdobjref,
|
||||
riid, chanbuf, &ifproxy);
|
||||
|
@ -1324,14 +1329,14 @@ StdMarshalImpl_UnmarshalInterface(IMarshal *iface, IStream *pStm, REFIID riid, v
|
|||
STDOBJREF stdobjref;
|
||||
ULONG res;
|
||||
HRESULT hres;
|
||||
APARTMENT *apt = COM_CurrentApt();
|
||||
APARTMENT *apt;
|
||||
APARTMENT *stub_apt;
|
||||
OXID oxid;
|
||||
|
||||
TRACE("(...,%s,....)\n", debugstr_guid(riid));
|
||||
|
||||
/* we need an apartment to unmarshal into */
|
||||
if (!apt)
|
||||
if (!(apt = apartment_get_current_or_mta()))
|
||||
{
|
||||
ERR("Apartment not initialized\n");
|
||||
return CO_E_NOTINITIALIZED;
|
||||
|
@ -1339,10 +1344,18 @@ StdMarshalImpl_UnmarshalInterface(IMarshal *iface, IStream *pStm, REFIID riid, v
|
|||
|
||||
/* read STDOBJREF from wire */
|
||||
hres = IStream_Read(pStm, &stdobjref, sizeof(stdobjref), &res);
|
||||
if (hres != S_OK) return STG_E_READFAULT;
|
||||
if (hres != S_OK)
|
||||
{
|
||||
apartment_release(apt);
|
||||
return STG_E_READFAULT;
|
||||
}
|
||||
|
||||
hres = apartment_getoxid(apt, &oxid);
|
||||
if (hres != S_OK) return hres;
|
||||
if (hres != S_OK)
|
||||
{
|
||||
apartment_release(apt);
|
||||
return hres;
|
||||
}
|
||||
|
||||
/* check if we're marshalling back to ourselves */
|
||||
if ((oxid == stdobjref.oxid) && (stubmgr = get_stub_manager(apt, stdobjref.oid)))
|
||||
|
@ -1357,6 +1370,7 @@ StdMarshalImpl_UnmarshalInterface(IMarshal *iface, IStream *pStm, REFIID riid, v
|
|||
stub_manager_ext_release(stubmgr, stdobjref.cPublicRefs, stdobjref.flags & SORFP_TABLEWEAK, FALSE);
|
||||
|
||||
stub_manager_int_release(stubmgr);
|
||||
apartment_release(apt);
|
||||
return hres;
|
||||
}
|
||||
|
||||
|
@ -1395,6 +1409,7 @@ StdMarshalImpl_UnmarshalInterface(IMarshal *iface, IStream *pStm, REFIID riid, v
|
|||
if (hres != S_OK) WARN("Failed with error 0x%08x\n", hres);
|
||||
else TRACE("Successfully created proxy %p\n", *ppv);
|
||||
|
||||
apartment_release(apt);
|
||||
return hres;
|
||||
}
|
||||
|
||||
|
|
|
@ -830,14 +830,16 @@ static HRESULT WINAPI ClientRpcChannelBuffer_SendReceive(LPRPCCHANNELBUFFER ifac
|
|||
ORPC_EXTENT_ARRAY orpc_ext_array;
|
||||
WIRE_ORPC_EXTENT *first_wire_orpc_extent = NULL;
|
||||
HRESULT hrFault = S_OK;
|
||||
APARTMENT *apt = apartment_get_current_or_mta();
|
||||
|
||||
TRACE("(%p) iMethod=%d\n", olemsg, olemsg->iMethod);
|
||||
|
||||
hr = ClientRpcChannelBuffer_IsCorrectApartment(This, COM_CurrentApt());
|
||||
hr = ClientRpcChannelBuffer_IsCorrectApartment(This, apt);
|
||||
if (hr != S_OK)
|
||||
{
|
||||
ERR("called from wrong apartment, should have been 0x%s\n",
|
||||
wine_dbgstr_longlong(This->oxid));
|
||||
if (apt) apartment_release(apt);
|
||||
return RPC_E_WRONG_THREAD;
|
||||
}
|
||||
/* This situation should be impossible in multi-threaded apartments,
|
||||
|
@ -845,11 +847,12 @@ static HRESULT WINAPI ClientRpcChannelBuffer_SendReceive(LPRPCCHANNELBUFFER ifac
|
|||
* Note: doing a COM call during the processing of a sent message is
|
||||
* only disallowed if a client call is already being waited for
|
||||
* completion */
|
||||
if (!COM_CurrentApt()->multi_threaded &&
|
||||
if (!apt->multi_threaded &&
|
||||
COM_CurrentInfo()->pending_call_count_client &&
|
||||
InSendMessage())
|
||||
{
|
||||
ERR("can't make an outgoing COM call in response to a sent message\n");
|
||||
apartment_release(apt);
|
||||
return RPC_E_CANTCALLOUT_ININPUTSYNCCALL;
|
||||
}
|
||||
|
||||
|
@ -967,6 +970,7 @@ static HRESULT WINAPI ClientRpcChannelBuffer_SendReceive(LPRPCCHANNELBUFFER ifac
|
|||
|
||||
TRACE("-- 0x%08x\n", hr);
|
||||
|
||||
apartment_release(apt);
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
@ -1094,7 +1098,7 @@ static const IRpcChannelBufferVtbl ServerRpcChannelBufferVtbl =
|
|||
HRESULT RPC_CreateClientChannel(const OXID *oxid, const IPID *ipid,
|
||||
const OXID_INFO *oxid_info,
|
||||
DWORD dest_context, void *dest_context_data,
|
||||
IRpcChannelBuffer **chan)
|
||||
IRpcChannelBuffer **chan, APARTMENT *apt)
|
||||
{
|
||||
ClientRpcChannelBuffer *This;
|
||||
WCHAR endpoint[200];
|
||||
|
@ -1148,7 +1152,7 @@ HRESULT RPC_CreateClientChannel(const OXID *oxid, const IPID *ipid,
|
|||
This->super.dest_context = dest_context;
|
||||
This->super.dest_context_data = dest_context_data;
|
||||
This->bind = bind;
|
||||
apartment_getoxid(COM_CurrentApt(), &This->oxid);
|
||||
apartment_getoxid(apt, &This->oxid);
|
||||
This->server_pid = oxid_info->dwPid;
|
||||
This->event = NULL;
|
||||
|
||||
|
@ -1644,7 +1648,7 @@ void RPC_StartRemoting(struct apartment *apt)
|
|||
|
||||
/* FIXME: move remote unknown exporting into this function */
|
||||
}
|
||||
start_apartment_remote_unknown();
|
||||
start_apartment_remote_unknown(apt);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -73,7 +73,8 @@ struct ifstub *stub_manager_new_ifstub(struct stub_manager *m, IRpcStubBuffer *s
|
|||
struct ifstub *stub;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("oid=%s, stubbuffer=%p, iid=%s\n", wine_dbgstr_longlong(m->oid), sb, debugstr_guid(iid));
|
||||
TRACE("oid=%s, stubbuffer=%p, iid=%s, dest_context=%x\n", wine_dbgstr_longlong(m->oid), sb,
|
||||
debugstr_guid(iid), dest_context);
|
||||
|
||||
stub = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct ifstub));
|
||||
if (!stub) return NULL;
|
||||
|
@ -470,7 +471,7 @@ ULONG stub_manager_ext_release(struct stub_manager *m, ULONG refs, BOOL tablewea
|
|||
/* gets the stub manager associated with an ipid - 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 */
|
||||
static struct stub_manager *get_stub_manager_from_ipid(APARTMENT *apt, const IPID *ipid)
|
||||
static struct stub_manager *get_stub_manager_from_ipid(APARTMENT *apt, const IPID *ipid, struct ifstub **ifstub)
|
||||
{
|
||||
struct stub_manager *result = NULL;
|
||||
struct list *cursor;
|
||||
|
@ -480,7 +481,7 @@ static struct stub_manager *get_stub_manager_from_ipid(APARTMENT *apt, const IPI
|
|||
{
|
||||
struct stub_manager *m = LIST_ENTRY( cursor, struct stub_manager, entry );
|
||||
|
||||
if (stub_manager_ipid_to_ifstub(m, ipid))
|
||||
if ((*ifstub = stub_manager_ipid_to_ifstub(m, ipid)))
|
||||
{
|
||||
result = m;
|
||||
stub_manager_int_addref(result);
|
||||
|
@ -497,7 +498,8 @@ static struct stub_manager *get_stub_manager_from_ipid(APARTMENT *apt, const IPI
|
|||
return result;
|
||||
}
|
||||
|
||||
static HRESULT ipid_to_stub_manager(const IPID *ipid, APARTMENT **stub_apt, struct stub_manager **stubmgr_ret)
|
||||
static HRESULT ipid_to_ifstub(const IPID *ipid, APARTMENT **stub_apt,
|
||||
struct stub_manager **stubmgr_ret, struct ifstub **ifstub)
|
||||
{
|
||||
/* FIXME: hack for IRemUnknown */
|
||||
if (ipid->Data2 == 0xffff)
|
||||
|
@ -509,7 +511,7 @@ static HRESULT ipid_to_stub_manager(const IPID *ipid, APARTMENT **stub_apt, stru
|
|||
TRACE("Couldn't find apartment corresponding to TID 0x%04x\n", ipid->Data2);
|
||||
return RPC_E_INVALID_OBJECT;
|
||||
}
|
||||
*stubmgr_ret = get_stub_manager_from_ipid(*stub_apt, ipid);
|
||||
*stubmgr_ret = get_stub_manager_from_ipid(*stub_apt, ipid, ifstub);
|
||||
if (!*stubmgr_ret)
|
||||
{
|
||||
apartment_release(*stub_apt);
|
||||
|
@ -519,6 +521,12 @@ static HRESULT ipid_to_stub_manager(const IPID *ipid, APARTMENT **stub_apt, stru
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT ipid_to_stub_manager(const IPID *ipid, APARTMENT **stub_apt, struct stub_manager **stub)
|
||||
{
|
||||
struct ifstub *ifstub;
|
||||
return ipid_to_ifstub(ipid, stub_apt, stub, &ifstub);
|
||||
}
|
||||
|
||||
/* gets the apartment, stub and channel of an object. the caller must
|
||||
* release the references to all objects (except iface) if the function
|
||||
* returned success, otherwise no references are returned. */
|
||||
|
@ -532,32 +540,22 @@ HRESULT ipid_get_dispatch_params(const IPID *ipid, APARTMENT **stub_apt,
|
|||
APARTMENT *apt;
|
||||
HRESULT hr;
|
||||
|
||||
hr = ipid_to_stub_manager(ipid, &apt, &stubmgr);
|
||||
hr = ipid_to_ifstub(ipid, &apt, &stubmgr, &ifstub);
|
||||
if (hr != S_OK) return RPC_E_DISCONNECTED;
|
||||
|
||||
ifstub = stub_manager_ipid_to_ifstub(stubmgr, ipid);
|
||||
if (ifstub)
|
||||
{
|
||||
*stub = ifstub->stubbuffer;
|
||||
IRpcStubBuffer_AddRef(*stub);
|
||||
*chan = ifstub->chan;
|
||||
IRpcChannelBuffer_AddRef(*chan);
|
||||
*stub_apt = apt;
|
||||
*iid = ifstub->iid;
|
||||
*iface = ifstub->iface;
|
||||
*stub = ifstub->stubbuffer;
|
||||
IRpcStubBuffer_AddRef(*stub);
|
||||
*chan = ifstub->chan;
|
||||
IRpcChannelBuffer_AddRef(*chan);
|
||||
*stub_apt = apt;
|
||||
*iid = ifstub->iid;
|
||||
*iface = ifstub->iface;
|
||||
|
||||
if (manager)
|
||||
*manager = stubmgr;
|
||||
else
|
||||
stub_manager_int_release(stubmgr);
|
||||
return S_OK;
|
||||
}
|
||||
if (manager)
|
||||
*manager = stubmgr;
|
||||
else
|
||||
{
|
||||
stub_manager_int_release(stubmgr);
|
||||
apartment_release(apt);
|
||||
return RPC_E_DISCONNECTED;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/* returns TRUE if it is possible to unmarshal, FALSE otherwise. */
|
||||
|
@ -707,18 +705,23 @@ static HRESULT WINAPI RemUnknown_RemQueryInterface(IRemUnknown *iface,
|
|||
USHORT successful_qis = 0;
|
||||
APARTMENT *apt;
|
||||
struct stub_manager *stubmgr;
|
||||
struct ifstub *ifstub;
|
||||
DWORD dest_context;
|
||||
void *dest_context_data;
|
||||
|
||||
TRACE("(%p)->(%s, %d, %d, %p, %p)\n", iface, debugstr_guid(ripid), cRefs, cIids, iids, ppQIResults);
|
||||
|
||||
hr = ipid_to_stub_manager(ripid, &apt, &stubmgr);
|
||||
hr = ipid_to_ifstub(ripid, &apt, &stubmgr, &ifstub);
|
||||
if (hr != S_OK) return hr;
|
||||
|
||||
IRpcChannelBuffer_GetDestCtx(ifstub->chan, &dest_context, &dest_context_data);
|
||||
|
||||
*ppQIResults = CoTaskMemAlloc(sizeof(REMQIRESULT) * cIids);
|
||||
|
||||
for (i = 0; i < cIids; i++)
|
||||
{
|
||||
HRESULT hrobj = marshal_object(apt, &(*ppQIResults)[i].std, &iids[i],
|
||||
stubmgr->object, MSHCTX_DIFFERENTMACHINE, NULL, MSHLFLAGS_NORMAL);
|
||||
stubmgr->object, dest_context, dest_context_data, MSHLFLAGS_NORMAL);
|
||||
if (hrobj == S_OK)
|
||||
successful_qis++;
|
||||
(*ppQIResults)[i].hResult = hrobj;
|
||||
|
@ -812,11 +815,10 @@ static const IRemUnknownVtbl RemUnknown_Vtbl =
|
|||
};
|
||||
|
||||
/* starts the IRemUnknown listener for the current apartment */
|
||||
HRESULT start_apartment_remote_unknown(void)
|
||||
HRESULT start_apartment_remote_unknown(APARTMENT *apt)
|
||||
{
|
||||
IRemUnknown *pRemUnknown;
|
||||
HRESULT hr = S_OK;
|
||||
APARTMENT *apt = COM_CurrentApt();
|
||||
|
||||
EnterCriticalSection(&apt->cs);
|
||||
if (!apt->remunk_exported)
|
||||
|
|
|
@ -387,7 +387,7 @@ ULONG __RPC_USER HGLOBAL_UserSize(ULONG *pFlags, ULONG StartingSize, HGLOBAL *ph
|
|||
|
||||
size += sizeof(ULONG);
|
||||
|
||||
if (LOWORD(*pFlags == MSHCTX_INPROC))
|
||||
if (LOWORD(*pFlags) == MSHCTX_INPROC)
|
||||
size += sizeof(HGLOBAL);
|
||||
else
|
||||
{
|
||||
|
@ -429,7 +429,7 @@ unsigned char * __RPC_USER HGLOBAL_UserMarshal(ULONG *pFlags, unsigned char *pBu
|
|||
|
||||
ALIGN_POINTER(pBuffer, 3);
|
||||
|
||||
if (LOWORD(*pFlags == MSHCTX_INPROC))
|
||||
if (LOWORD(*pFlags) == MSHCTX_INPROC)
|
||||
{
|
||||
if (sizeof(*phGlobal) == 8)
|
||||
*(ULONG *)pBuffer = WDT_INPROC64_CALL;
|
||||
|
@ -572,7 +572,7 @@ void __RPC_USER HGLOBAL_UserFree(ULONG *pFlags, HGLOBAL *phGlobal)
|
|||
{
|
||||
TRACE("(%s, &%p\n", debugstr_user_flags(pFlags), *phGlobal);
|
||||
|
||||
if (LOWORD(*pFlags != MSHCTX_INPROC) && *phGlobal)
|
||||
if (LOWORD(*pFlags) != MSHCTX_INPROC && *phGlobal)
|
||||
GlobalFree(*phGlobal);
|
||||
}
|
||||
|
||||
|
|
|
@ -139,7 +139,7 @@ reactos/dll/win32/ntdsapi # Synced to WineStaging-3.9
|
|||
reactos/dll/win32/objsel # Synced to WineStaging-3.3
|
||||
reactos/dll/win32/odbc32 # Synced to WineStaging-3.3. Depends on port of Linux ODBC.
|
||||
reactos/dll/win32/odbccp32 # Synced to WineStaging-3.9
|
||||
reactos/dll/win32/ole32 # Synced to WineStaging-3.3
|
||||
reactos/dll/win32/ole32 # Synced to WineStaging-3.9
|
||||
reactos/dll/win32/oleacc # Synced to WineStaging-3.3
|
||||
reactos/dll/win32/oleaut32 # Synced to WineStaging-3.3
|
||||
reactos/dll/win32/olecli32 # Synced to WineStaging-3.3
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue