[OLE32] Sync with Wine Staging 3.9. CORE-14656
authorAmine Khaldi <amine.khaldi@reactos.org>
Mon, 4 Jun 2018 02:45:35 +0000 (03:45 +0100)
committerAmine Khaldi <amine.khaldi@reactos.org>
Mon, 4 Jun 2018 02:45:35 +0000 (03:45 +0100)
dll/win32/ole32/compobj.c
dll/win32/ole32/compobj_private.h
dll/win32/ole32/datacache.c
dll/win32/ole32/marshal.c
dll/win32/ole32/rpc.c
dll/win32/ole32/stubmanager.c
dll/win32/ole32/usrmarshal.c
media/doc/README.WINE

index 4cb8f4b..2f4a69a 100644 (file)
@@ -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;
 }
 
index 9e65c3e..212d328 100644 (file)
@@ -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 *) */
index 325a98b..b72b8ff 100644 (file)
@@ -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, &current_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;
+    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 (cache_entry->load_stream_num != STREAM_NUMBER_CONTENTS)
     {
-        FIXME( "Unimplemented for presentation stream\n" );
-        return E_FAIL;
+        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_Stat( stm, &stat, STATFLAG_NONAME );
+    hr = IStream_Seek( stm, offset_zero, STREAM_SEEK_CUR, &current_pos );
     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);
+    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 );
index b39dac0..7c0f541 100644 (file)
@@ -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;
 }
 
index 8d8276e..a73d23c 100644 (file)
@@ -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);
 }
 
 
index 57048c6..5f604d4 100644 (file)
@@ -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;
-
-        if (manager)
-            *manager = stubmgr;
-        else
-            stub_manager_int_release(stubmgr);
-        return S_OK;
-    }
+    *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);
-        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)
index 63eead1..8d36e13 100644 (file)
@@ -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);
 }
 
index 829a988..c3ec642 100644 (file)
@@ -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