[OLE32] Sync with Wine Staging 4.0. CORE-15682
authorAmine Khaldi <amine.khaldi@reactos.org>
Tue, 29 Jan 2019 12:15:33 +0000 (13:15 +0100)
committerAmine Khaldi <amine.khaldi@reactos.org>
Tue, 29 Jan 2019 12:15:33 +0000 (13:15 +0100)
16 files changed:
dll/win32/ole32/classmoniker.c
dll/win32/ole32/clipboard.c
dll/win32/ole32/compobj.c
dll/win32/ole32/compobj_private.h
dll/win32/ole32/datacache.c
dll/win32/ole32/ftmarshal.c
dll/win32/ole32/git.c
dll/win32/ole32/marshal.c
dll/win32/ole32/moniker.c
dll/win32/ole32/ole2.c
dll/win32/ole32/ole2impl.c
dll/win32/ole32/rpc.c
dll/win32/ole32/stg_prop.c
dll/win32/ole32/storage32.c
dll/win32/ole32/usrmarshal.c
media/doc/README.WINE

index ebad794..30a24d2 100644 (file)
@@ -536,14 +536,14 @@ static HRESULT WINAPI ClassMoniker_GetDisplayName(IMoniker* iface,
 
     *ppszDisplayName = CoTaskMemAlloc(sizeof(wszClsidPrefix) + (CHARS_IN_GUID-2) * sizeof(WCHAR));
 
-    StringFromGUID2(&This->clsid, *ppszDisplayName+sizeof(wszClsidPrefix)/sizeof(WCHAR)-2, CHARS_IN_GUID);
+    StringFromGUID2(&This->clsid, *ppszDisplayName+ARRAY_SIZE(wszClsidPrefix)-2, CHARS_IN_GUID);
 
     /* note: this overwrites the opening curly bracket of the CLSID string generated above */
     memcpy(*ppszDisplayName, wszClsidPrefix, sizeof(wszClsidPrefix)-sizeof(WCHAR));
 
     /* note: this overwrites the closing curly bracket of the CLSID string generated above */
-    (*ppszDisplayName)[sizeof(wszClsidPrefix)/sizeof(WCHAR)-2+CHARS_IN_GUID-2] = ':';
-    (*ppszDisplayName)[sizeof(wszClsidPrefix)/sizeof(WCHAR)-2+CHARS_IN_GUID-1] = '\0';
+    (*ppszDisplayName)[ARRAY_SIZE(wszClsidPrefix)-2+CHARS_IN_GUID-2] = ':';
+    (*ppszDisplayName)[ARRAY_SIZE(wszClsidPrefix)-2+CHARS_IN_GUID-1] = '\0';
 
     TRACE("string is %s\n", debugstr_w(*ppszDisplayName));
     return S_OK;
index 9448f5b..f3e9a6b 100644 (file)
@@ -1197,7 +1197,7 @@ static HRESULT get_priv_data(ole_priv_data **data)
         for(cf = 0; (cf = EnumClipboardFormats(cf)) != 0; count++)
         {
             WCHAR buf[256];
-            if (GetClipboardFormatNameW(cf, buf, sizeof(buf) / sizeof(WCHAR)))
+            if (GetClipboardFormatNameW(cf, buf, ARRAY_SIZE(buf)))
                 TRACE("cf %04x %s\n", cf, debugstr_w(buf));
             else
                 TRACE("cf %04x\n", cf);
@@ -1296,6 +1296,14 @@ static HRESULT get_stgmed_for_storage(HGLOBAL h, STGMEDIUM *med)
         return hr;
     }
 
+    hr = StgIsStorageILockBytes(lbs);
+    if(hr!=S_OK)
+    {
+        ILockBytes_Release(lbs);
+        GlobalFree(dst);
+        return SUCCEEDED(hr) ? E_FAIL : hr;
+    }
+
     hr = StgOpenStorageOnILockBytes(lbs, NULL,  STGM_SHARE_EXCLUSIVE | STGM_READWRITE, NULL, 0, &med->u.pstg);
     ILockBytes_Release(lbs);
     if(FAILED(hr))
@@ -1402,12 +1410,19 @@ static HRESULT WINAPI snapshot_GetData(IDataObject *iface, FORMATETC *fmt,
     if(This->data)
     {
         hr = IDataObject_GetData(This->data, fmt, med);
-        CloseClipboard();
-        return hr;
+        if(SUCCEEDED(hr))
+        {
+            CloseClipboard();
+            return hr;
+        }
+    }
+    if(fmt->lindex != -1)
+    {
+        hr = DV_E_FORMATETC;
+        goto end;
     }
 
-    h = GetClipboardData(fmt->cfFormat);
-    if(!h)
+    if(!IsClipboardFormatAvailable(fmt->cfFormat))
     {
         hr = DV_E_FORMATETC;
         goto end;
@@ -1425,17 +1440,31 @@ static HRESULT WINAPI snapshot_GetData(IDataObject *iface, FORMATETC *fmt,
             goto end;
         }
         mask = fmt->tymed & entry->fmtetc.tymed;
-        if(!mask) mask = fmt->tymed & (TYMED_ISTREAM | TYMED_HGLOBAL);
+        if(!mask && (entry->fmtetc.tymed & (TYMED_ISTREAM | TYMED_HGLOBAL | TYMED_ISTORAGE)))
+            mask = fmt->tymed & (TYMED_ISTREAM | TYMED_HGLOBAL | TYMED_ISTORAGE);
     }
     else /* non-Ole format */
-        mask = fmt->tymed & TYMED_HGLOBAL;
+        mask = fmt->tymed & get_tymed_from_nonole_cf(fmt->cfFormat);
 
-    if(mask & TYMED_ISTORAGE)
-        hr = get_stgmed_for_storage(h, med);
-    else if(mask & TYMED_HGLOBAL)
+    if(!mask)
+    {
+        hr = DV_E_TYMED;
+        goto end;
+    }
+
+    h = GetClipboardData(fmt->cfFormat);
+    if(!h)
+    {
+        hr = DV_E_FORMATETC;
+        goto end;
+    }
+
+    if(mask & TYMED_HGLOBAL)
         hr = get_stgmed_for_global(h, med);
     else if(mask & TYMED_ISTREAM)
         hr = get_stgmed_for_stream(h, med);
+    else if(mask & TYMED_ISTORAGE)
+        hr = get_stgmed_for_storage(h, med);
     else if(mask & TYMED_ENHMF)
         hr = get_stgmed_for_emf((HENHMETAFILE)h, med);
     else if(mask & TYMED_GDI)
index 2f4a69a..eae3933 100644 (file)
@@ -60,6 +60,7 @@
 #include "ctxtcall.h"
 #include "dde.h"
 #include "servprov.h"
+
 #ifndef __REACTOS__
 #include "initguid.h"
 #endif
@@ -71,9 +72,6 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(ole);
 
-#undef ARRAYSIZE
-#define ARRAYSIZE(array) (sizeof(array)/sizeof((array)[0]))
-
 /****************************************************************************
  * This section defines variables internal to the COM module.
  */
@@ -485,6 +483,8 @@ struct apartment_loaded_dll
 
 static const WCHAR wszAptWinClass[] = {'O','l','e','M','a','i','n','T','h','r','e','a','d','W','n','d','C','l','a','s','s',0};
 
+static ATOM apt_win_class;
+
 /*****************************************************************************
  * This section contains OpenDllList implementation
  */
@@ -1412,12 +1412,8 @@ static HRESULT apartment_getclassobject(struct apartment *apt, LPCWSTR dllpath,
     return hr;
 }
 
-/***********************************************************************
- *     COM_RegReadPath [internal]
- *
- *     Reads a registry value and expands it when necessary
- */
-static DWORD COM_RegReadPath(const struct class_reg_data *regdata, WCHAR *dst, DWORD dstlen)
+/* Returns expanded dll path from the registry or activation context. */
+static BOOL get_object_dll_path(const struct class_reg_data *regdata, WCHAR *dst, DWORD dstlen)
 {
     DWORD ret;
 
@@ -1444,19 +1440,20 @@ static DWORD COM_RegReadPath(const struct class_reg_data *regdata, WCHAR *dst, D
               lstrcpynW(dst, src, dstlen);
             }
         }
-       return ret;
+        return !ret;
     }
     else
     {
+        static const WCHAR dllW[] = {'.','d','l','l',0};
         ULONG_PTR cookie;
         WCHAR *nameW;
 
         *dst = 0;
         nameW = (WCHAR*)((BYTE*)regdata->u.actctx.section + regdata->u.actctx.data->name_offset);
         ActivateActCtx(regdata->u.actctx.hactctx, &cookie);
-        ret = SearchPathW(NULL, nameW, NULL, dstlen, dst, NULL);
+        ret = SearchPathW(NULL, nameW, dllW, dstlen, dst, NULL);
         DeactivateActCtx(0, cookie);
-        return !*dst;
+        return *dst != 0;
     }
 }
 
@@ -1481,7 +1478,7 @@ static HRESULT apartment_hostobject(struct apartment *apt,
 
     TRACE("clsid %s, iid %s\n", debugstr_guid(&params->clsid), debugstr_guid(&params->iid));
 
-    if (COM_RegReadPath(&params->regdata, dllpath, ARRAYSIZE(dllpath)) != ERROR_SUCCESS)
+    if (!get_object_dll_path(&params->regdata, dllpath, ARRAY_SIZE(dllpath)))
     {
         /* failure: CLSID is not found in registry */
         WARN("class %s not registered inproc\n", debugstr_guid(&params->clsid));
@@ -1701,7 +1698,7 @@ static BOOL WINAPI register_class( INIT_ONCE *once, void *param, void **context
     wclass.lpfnWndProc = apartment_wndproc;
     wclass.hInstance = hProxyDll;
     wclass.lpszClassName = wszAptWinClass;
-    RegisterClassW(&wclass);
+    apt_win_class = RegisterClassW(&wclass);
     return TRUE;
 }
 
@@ -2360,7 +2357,7 @@ INT WINAPI StringFromGUID2(REFGUID id, LPOLESTR str, INT cmax)
 HRESULT COM_OpenKeyForCLSID(REFCLSID clsid, LPCWSTR keyname, REGSAM access, HKEY *subkey)
 {
     static const WCHAR wszCLSIDSlash[] = {'C','L','S','I','D','\\',0};
-    WCHAR path[CHARS_IN_GUID + ARRAYSIZE(wszCLSIDSlash) - 1];
+    WCHAR path[CHARS_IN_GUID + ARRAY_SIZE(wszCLSIDSlash) - 1];
     LONG res;
     HKEY key;
 
@@ -2395,7 +2392,7 @@ HRESULT COM_OpenKeyForAppIdFromCLSID(REFCLSID clsid, REGSAM access, HKEY *subkey
     static const WCHAR szAppIdKey[] = { 'A','p','p','I','d','\\',0 };
     DWORD res;
     WCHAR buf[CHARS_IN_GUID];
-    WCHAR keyname[ARRAYSIZE(szAppIdKey) + CHARS_IN_GUID];
+    WCHAR keyname[ARRAY_SIZE(szAppIdKey) + CHARS_IN_GUID];
     DWORD size;
     HKEY hkey;
     DWORD type;
@@ -2603,7 +2600,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)];
+    WCHAR path[ARRAY_SIZE(wszInterface) - 1 + CHARS_IN_GUID - 1 + ARRAY_SIZE(wszPSC)];
     APARTMENT *apt;
     struct registered_psclsid *registered_psclsid;
     ACTCTX_SECTION_KEYED_DATA data;
@@ -2646,8 +2643,8 @@ HRESULT WINAPI CoGetPSClsid(REFIID riid, CLSID *pclsid)
 
     /* Interface\\{string form of riid}\\ProxyStubClsid32 */
     strcpyW(path, wszInterface);
-    StringFromGUID2(riid, path + ARRAYSIZE(wszInterface) - 1, CHARS_IN_GUID);
-    strcpyW(path + ARRAYSIZE(wszInterface) - 1 + CHARS_IN_GUID - 1, wszPSC);
+    StringFromGUID2(riid, path + ARRAY_SIZE(wszInterface) - 1, CHARS_IN_GUID);
+    strcpyW(path + ARRAY_SIZE(wszInterface) - 1 + CHARS_IN_GUID - 1, wszPSC);
 
     hr = get_ps_clsid_from_registry(path, 0, pclsid);
     if (FAILED(hr) && (opposite == KEY_WOW64_32KEY ||
@@ -2975,7 +2972,7 @@ static HRESULT get_inproc_class_object(APARTMENT *apt, const struct class_reg_da
     else
         apartment_threaded = !apt->multi_threaded;
 
-    if (COM_RegReadPath(regdata, dllpath, ARRAYSIZE(dllpath)) != ERROR_SUCCESS)
+    if (!get_object_dll_path(regdata, dllpath, ARRAY_SIZE(dllpath)))
     {
         /* failure: CLSID is not found in registry */
         WARN("class %s not registered inproc\n", debugstr_guid(rclsid));
@@ -3833,7 +3830,7 @@ HRESULT WINAPI CoTreatAsClass(REFCLSID clsidOld, REFCLSID clsidNew)
         if(IsEqualGUID(clsidNew, &CLSID_NULL)){
            RegDeleteKeyW(hkey, wszTreatAs);
         }else{
-            if(!StringFromGUID2(clsidNew, szClsidNew, ARRAYSIZE(szClsidNew))){
+            if(!StringFromGUID2(clsidNew, szClsidNew, ARRAY_SIZE(szClsidNew))){
                 WARN("StringFromGUID2 failed\n");
                 res = E_FAIL;
                 goto done;
@@ -5091,7 +5088,7 @@ HRESULT Handler_DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
         regdata.u.hkey = hkey;
         regdata.hkey = TRUE;
 
-        if (COM_RegReadPath(&regdata, dllpath, ARRAYSIZE(dllpath)) == ERROR_SUCCESS)
+        if (get_object_dll_path(&regdata, dllpath, ARRAY_SIZE(dllpath)))
         {
             static const WCHAR wszOle32[] = {'o','l','e','3','2','.','d','l','l',0};
             if (!strcmpiW(dllpath, wszOle32))
@@ -5276,7 +5273,8 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID reserved)
     case DLL_PROCESS_DETACH:
         if (reserved) break;
         release_std_git();
-        UnregisterClassW( wszAptWinClass, hProxyDll );
+        if(apt_win_class)
+            UnregisterClassW( (const WCHAR*)MAKEINTATOM(apt_win_class), hProxyDll );
         RPC_UnregisterAllChannelHooks();
         COMPOBJ_DllList_Free();
         DeleteCriticalSection(&csRegisteredClassList);
index 212d328..1e564a3 100644 (file)
@@ -210,7 +210,7 @@ struct dispatch_params;
 
 void    RPC_StartRemoting(struct apartment *apt) DECLSPEC_HIDDEN;
 HRESULT RPC_CreateClientChannel(const OXID *oxid, const IPID *ipid,
-                                const OXID_INFO *oxid_info,
+                                const OXID_INFO *oxid_info, const IID *iid,
                                 DWORD dest_context, void *dest_context_data,
                                 IRpcChannelBuffer **chan, APARTMENT *apt) DECLSPEC_HIDDEN;
 HRESULT RPC_CreateServerChannel(DWORD dest_context, void *dest_context_data, IRpcChannelBuffer **chan) DECLSPEC_HIDDEN;
index b72b8ff..3eff569 100644 (file)
@@ -2667,7 +2667,7 @@ static HRESULT WINAPI DataCache_UpdateCache( IOleCache2 *iface, IDataObject *dat
         }
         else
         {
-            for (i = 0; i < sizeof(view_list) / sizeof(view_list[0]); i++)
+            for (i = 0; i < ARRAY_SIZE(view_list); i++)
             {
                 fmt.cfFormat = view_list[i];
                 fmt.tymed = tymed_from_cf( fmt.cfFormat );
index 3eb7f87..c36f5f6 100644 (file)
@@ -144,7 +144,7 @@ FTMarshalImpl_GetUnmarshalClass (LPMARSHAL iface, REFIID riid, void *pv, DWORD d
     if (dwDestContext == MSHCTX_INPROC || dwDestContext == MSHCTX_CROSSCTX)
         *pCid = CLSID_InProcFreeMarshaler;
     else
-        *pCid = CLSID_DfMarshal;
+        *pCid = CLSID_StdMarshal;
     return S_OK;
 }
 
index f7a0460..8683f35 100644 (file)
@@ -122,9 +122,14 @@ StdGlobalInterfaceTable_QueryInterface(IGlobalInterfaceTable* iface,
   /* Do we implement that interface? */
   if (IsEqualIID(&IID_IUnknown, riid) ||
       IsEqualIID(&IID_IGlobalInterfaceTable, riid))
+  {
     *ppvObject = iface;
+  }
   else
+  {
+    FIXME("(%s), not supported.\n", debugstr_guid(riid));
     return E_NOINTERFACE;
+  }
 
   /* Now inc the refcount */
   IGlobalInterfaceTable_AddRef(iface);
@@ -314,13 +319,10 @@ static HRESULT WINAPI
 GITCF_CreateInstance(LPCLASSFACTORY iface, LPUNKNOWN pUnk,
                      REFIID riid, LPVOID *ppv)
 {
-  if (IsEqualIID(riid,&IID_IGlobalInterfaceTable)) {
-    IGlobalInterfaceTable *git = get_std_git();
-    return IGlobalInterfaceTable_QueryInterface(git, riid, ppv);
-  }
-
-  FIXME("(%s), not supported.\n",debugstr_guid(riid));
-  return E_NOINTERFACE;
+  IGlobalInterfaceTable *git = get_std_git();
+  HRESULT hr = IGlobalInterfaceTable_QueryInterface(git, riid, ppv);
+  IGlobalInterfaceTable_Release(git);
+  return hr;
 }
 
 static HRESULT WINAPI GITCF_LockServer(LPCLASSFACTORY iface, BOOL fLock)
index 7c0f541..b12082c 100644 (file)
@@ -40,8 +40,6 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(ole);
 
-extern const CLSID CLSID_DfMarshal;
-
 /* number of refs given out for normal marshaling */
 #define NORMALEXTREFS 5
 
@@ -362,12 +360,7 @@ static const IMultiQIVtbl ClientIdentity_Vtbl =
     ClientIdentity_QueryMultipleInterfaces
 };
 
-/* FIXME: remove these */
-static HRESULT WINAPI StdMarshalImpl_GetUnmarshalClass(LPMARSHAL iface, REFIID riid, void* pv, DWORD dwDestContext, void* pvDestContext, DWORD mshlflags, CLSID* pCid);
-static HRESULT WINAPI StdMarshalImpl_GetMarshalSizeMax(LPMARSHAL iface, REFIID riid, void* pv, DWORD dwDestContext, void* pvDestContext, DWORD mshlflags, DWORD* pSize);
-static HRESULT WINAPI StdMarshalImpl_UnmarshalInterface(LPMARSHAL iface, IStream *pStm, REFIID riid, void **ppv);
-static HRESULT WINAPI StdMarshalImpl_ReleaseMarshalData(LPMARSHAL iface, IStream *pStm);
-static HRESULT WINAPI StdMarshalImpl_DisconnectObject(LPMARSHAL iface, DWORD dwReserved);
+static HRESULT StdMarshalImpl_Construct(REFIID, DWORD, void*, void**);
 
 static HRESULT WINAPI Proxy_QueryInterface(IMarshal *iface, REFIID riid, void **ppvObject)
 {
@@ -387,6 +380,33 @@ static ULONG WINAPI Proxy_Release(IMarshal *iface)
     return IMultiQI_Release(&This->IMultiQI_iface);
 }
 
+static HRESULT WINAPI Proxy_GetUnmarshalClass(
+    IMarshal *iface, REFIID riid, void* pv, DWORD dwDestContext,
+    void* pvDestContext, DWORD mshlflags, CLSID* pCid)
+{
+    *pCid = CLSID_StdMarshal;
+    return S_OK;
+}
+
+static HRESULT WINAPI Proxy_GetMarshalSizeMax(
+    IMarshal *iface, REFIID riid, void* pv, DWORD dwDestContext,
+    void* pvDestContext, DWORD mshlflags, DWORD* pSize)
+{
+    *pSize = FIELD_OFFSET(OBJREF, u_objref.u_standard.saResAddr.aStringArray);
+    return S_OK;
+}
+
+static void fill_std_objref(OBJREF *objref, const GUID *iid, STDOBJREF *std)
+{
+    objref->signature = OBJREF_SIGNATURE;
+    objref->flags = OBJREF_STANDARD;
+    objref->iid = *iid;
+    if(std)
+        objref->u_objref.u_standard.std = *std;
+    memset(&objref->u_objref.u_standard.saResAddr, 0,
+            sizeof(objref->u_objref.u_standard.saResAddr));
+}
+
 static HRESULT WINAPI Proxy_MarshalInterface(
     LPMARSHAL iface, IStream *pStm, REFIID riid, void* pv, DWORD dwDestContext,
     void* pvDestContext, DWORD mshlflags)
@@ -450,12 +470,16 @@ static HRESULT WINAPI Proxy_MarshalInterface(
 
         if (SUCCEEDED(hr))
         {
+            OBJREF objref;
+
             TRACE("writing stdobjref: flags = %04x cPublicRefs = %d oxid = %s oid = %s ipid = %s\n",
                 stdobjref.flags, stdobjref.cPublicRefs,
                 wine_dbgstr_longlong(stdobjref.oxid),
                 wine_dbgstr_longlong(stdobjref.oid),
                 debugstr_guid(&stdobjref.ipid));
-            hr = IStream_Write(pStm, &stdobjref, sizeof(stdobjref), NULL);
+            fill_std_objref(&objref, riid, &stdobjref);
+            hr = IStream_Write(pStm, &objref, FIELD_OFFSET(OBJREF,
+                        u_objref.u_standard.saResAddr.aStringArray), NULL);
         }
     }
     else
@@ -481,7 +505,11 @@ static HRESULT WINAPI Proxy_MarshalInterface(
                                                1, &iid, &qiresults);
             if (SUCCEEDED(hr))
             {
-                hr = IStream_Write(pStm, &qiresults->std, sizeof(qiresults->std), NULL);
+                OBJREF objref;
+
+                fill_std_objref(&objref, riid, &qiresults->std);
+                hr = IStream_Write(pStm, &objref, FIELD_OFFSET(OBJREF,
+                            u_objref.u_standard.saResAddr.aStringArray), NULL);
                 if (FAILED(hr))
                 {
                     REMINTERFACEREF rif;
@@ -501,17 +529,72 @@ static HRESULT WINAPI Proxy_MarshalInterface(
     return hr;
 }
 
+static HRESULT WINAPI Proxy_UnmarshalInterface(
+        IMarshal *iface, IStream *pStm, REFIID riid, void **ppv)
+{
+    struct proxy_manager *This = impl_from_IMarshal( iface );
+    IMarshal *marshal;
+    HRESULT hr;
+
+    TRACE("(%p, %p, %s, %p)\n", This, pStm, wine_dbgstr_guid(riid), ppv);
+
+    hr = StdMarshalImpl_Construct(&IID_IMarshal, This->dest_context,
+            This->dest_context_data, (void**)&marshal);
+    if(FAILED(hr))
+        return hr;
+
+    hr = IMarshal_UnmarshalInterface(marshal, pStm, riid, ppv);
+    IMarshal_Release(marshal);
+    return hr;
+}
+
+static HRESULT WINAPI Proxy_ReleaseMarshalData(IMarshal *iface, IStream *pStm)
+{
+    struct proxy_manager *This = impl_from_IMarshal( iface );
+    IMarshal *marshal;
+    HRESULT hr;
+
+    TRACE("(%p, %p)\n", This, pStm);
+
+    hr = StdMarshalImpl_Construct(&IID_IMarshal, This->dest_context,
+            This->dest_context_data, (void**)&marshal);
+    if(FAILED(hr))
+        return hr;
+
+    hr = IMarshal_ReleaseMarshalData(marshal, pStm);
+    IMarshal_Release(marshal);
+    return hr;
+}
+
+static HRESULT WINAPI Proxy_DisconnectObject(IMarshal *iface, DWORD dwReserved)
+{
+    struct proxy_manager *This = impl_from_IMarshal( iface );
+    IMarshal *marshal;
+    HRESULT hr;
+
+    TRACE("(%p, %x)\n", This, dwReserved);
+
+    hr = StdMarshalImpl_Construct(&IID_IMarshal, This->dest_context,
+            This->dest_context_data, (void**)&marshal);
+    if(FAILED(hr))
+        return hr;
+
+    hr = IMarshal_DisconnectObject(marshal, dwReserved);
+    IMarshal_Release(marshal);
+    return hr;
+}
+
 static const IMarshalVtbl ProxyMarshal_Vtbl =
 {
     Proxy_QueryInterface,
     Proxy_AddRef,
     Proxy_Release,
-    StdMarshalImpl_GetUnmarshalClass,
-    StdMarshalImpl_GetMarshalSizeMax,
+    Proxy_GetUnmarshalClass,
+    Proxy_GetMarshalSizeMax,
     Proxy_MarshalInterface,
-    StdMarshalImpl_UnmarshalInterface,
-    StdMarshalImpl_ReleaseMarshalData,
-    StdMarshalImpl_DisconnectObject
+    Proxy_UnmarshalInterface,
+    Proxy_ReleaseMarshalData,
+    Proxy_DisconnectObject
 };
 
 static HRESULT WINAPI ProxyCliSec_QueryInterface(IClientSecurity *iface, REFIID riid, void **ppvObject)
@@ -1204,7 +1287,7 @@ StdMarshalImpl_GetUnmarshalClass(
     IMarshal *iface, REFIID riid, void* pv, DWORD dwDestContext,
     void* pvDestContext, DWORD mshlflags, CLSID* pCid)
 {
-    *pCid = CLSID_DfMarshal;
+    *pCid = CLSID_StdMarshal;
     return S_OK;
 }
 
@@ -1213,7 +1296,7 @@ StdMarshalImpl_GetMarshalSizeMax(
     IMarshal *iface, REFIID riid, void* pv, DWORD dwDestContext,
     void* pvDestContext, DWORD mshlflags, DWORD* pSize)
 {
-    *pSize = sizeof(STDOBJREF);
+    *pSize = FIELD_OFFSET(OBJREF, u_objref.u_standard.saResAddr.aStringArray);
     return S_OK;
 }
 
@@ -1222,10 +1305,10 @@ StdMarshalImpl_MarshalInterface(
     IMarshal *iface, IStream *pStm,REFIID riid, void* pv, DWORD dest_context,
     void* dest_context_data, DWORD mshlflags)
 {
-    STDOBJREF             stdobjref;
     ULONG                 res;
     HRESULT               hres;
     APARTMENT *apt;
+    OBJREF objref;
 
     TRACE("(...,%s,...)\n", debugstr_guid(riid));
 
@@ -1238,7 +1321,9 @@ StdMarshalImpl_MarshalInterface(
     /* make sure this apartment can be reached from other threads / processes */
     RPC_StartRemoting(apt);
 
-    hres = marshal_object(apt, &stdobjref, riid, pv, dest_context, dest_context_data, mshlflags);
+    fill_std_objref(&objref, riid, NULL);
+    hres = marshal_object(apt, &objref.u_objref.u_standard.std, riid,
+            pv, dest_context, dest_context_data, mshlflags);
     apartment_release(apt);
     if (hres != S_OK)
     {
@@ -1246,7 +1331,8 @@ StdMarshalImpl_MarshalInterface(
         return hres;
     }
 
-    return IStream_Write(pStm, &stdobjref, sizeof(stdobjref), &res);
+    return IStream_Write(pStm, &objref,
+            FIELD_OFFSET(OBJREF, u_objref.u_standard.saResAddr.aStringArray), &res);
 }
 
 /* helper for StdMarshalImpl_UnmarshalInterface - does the unmarshaling with
@@ -1290,7 +1376,7 @@ static HRESULT unmarshal_object(const STDOBJREF *stdobjref, APARTMENT *apt,
         {
             IRpcChannelBuffer *chanbuf;
             hr = RPC_CreateClientChannel(&stdobjref->oxid, &stdobjref->ipid,
-                                         &proxy_manager->oxid_info,
+                                         &proxy_manager->oxid_info, riid,
                                          proxy_manager->dest_context,
                                          proxy_manager->dest_context_data,
                                          &chanbuf, apt);
@@ -1321,12 +1407,11 @@ static HRESULT unmarshal_object(const STDOBJREF *stdobjref, APARTMENT *apt,
     return hr;
 }
 
-static HRESULT WINAPI
-StdMarshalImpl_UnmarshalInterface(IMarshal *iface, IStream *pStm, REFIID riid, void **ppv)
+static HRESULT std_unmarshal_interface(MSHCTX dest_context, void *dest_context_data,
+        IStream *pStm, REFIID riid, void **ppv)
 {
-    StdMarshalImpl *This = impl_from_StdMarshal(iface);
     struct stub_manager *stubmgr = NULL;
-    STDOBJREF stdobjref;
+    struct OR_STANDARD obj;
     ULONG res;
     HRESULT hres;
     APARTMENT *apt;
@@ -1343,7 +1428,7 @@ StdMarshalImpl_UnmarshalInterface(IMarshal *iface, IStream *pStm, REFIID riid, v
     }
 
     /* read STDOBJREF from wire */
-    hres = IStream_Read(pStm, &stdobjref, sizeof(stdobjref), &res);
+    hres = IStream_Read(pStm, &obj, FIELD_OFFSET(struct OR_STANDARD, saResAddr.aStringArray), &res);
     if (hres != S_OK)
     {
         apartment_release(apt);
@@ -1357,8 +1442,14 @@ StdMarshalImpl_UnmarshalInterface(IMarshal *iface, IStream *pStm, REFIID riid, v
         return hres;
     }
 
+    if (obj.saResAddr.wNumEntries)
+    {
+        ERR("unsupported size of DUALSTRINGARRAY\n");
+        return E_NOTIMPL;
+    }
+
     /* check if we're marshalling back to ourselves */
-    if ((oxid == stdobjref.oxid) && (stubmgr = get_stub_manager(apt, stdobjref.oid)))
+    if ((oxid == obj.std.oxid) && (stubmgr = get_stub_manager(apt, obj.std.oid)))
     {
         TRACE("Unmarshalling object marshalled in same apartment for iid %s, "
               "returning original object %p\n", debugstr_guid(riid), stubmgr->object);
@@ -1366,8 +1457,8 @@ StdMarshalImpl_UnmarshalInterface(IMarshal *iface, IStream *pStm, REFIID riid, v
         hres = IUnknown_QueryInterface(stubmgr->object, riid, ppv);
       
         /* unref the ifstub. FIXME: only do this on success? */
-        if (!stub_manager_is_table_marshaled(stubmgr, &stdobjref.ipid))
-            stub_manager_ext_release(stubmgr, stdobjref.cPublicRefs, stdobjref.flags & SORFP_TABLEWEAK, FALSE);
+        if (!stub_manager_is_table_marshaled(stubmgr, &obj.std.ipid))
+            stub_manager_ext_release(stubmgr, obj.std.cPublicRefs, obj.std.flags & SORFP_TABLEWEAK, FALSE);
 
         stub_manager_int_release(stubmgr);
         apartment_release(apt);
@@ -1379,28 +1470,28 @@ StdMarshalImpl_UnmarshalInterface(IMarshal *iface, IStream *pStm, REFIID riid, v
      * ignore table marshaling and normal marshaling rules regarding number of
      * unmarshals, etc, but if you abuse these rules then your proxy could end
      * up returning RPC_E_DISCONNECTED. */
-    if ((stub_apt = apartment_findfromoxid(stdobjref.oxid, TRUE)))
+    if ((stub_apt = apartment_findfromoxid(obj.std.oxid, TRUE)))
     {
-        if ((stubmgr = get_stub_manager(stub_apt, stdobjref.oid)))
+        if ((stubmgr = get_stub_manager(stub_apt, obj.std.oid)))
         {
-            if (!stub_manager_notify_unmarshal(stubmgr, &stdobjref.ipid))
+            if (!stub_manager_notify_unmarshal(stubmgr, &obj.std.ipid))
                 hres = CO_E_OBJNOTCONNECTED;
         }
         else
         {
             WARN("Couldn't find object for OXID %s, OID %s, assuming disconnected\n",
-                wine_dbgstr_longlong(stdobjref.oxid),
-                wine_dbgstr_longlong(stdobjref.oid));
+                wine_dbgstr_longlong(obj.std.oxid),
+                wine_dbgstr_longlong(obj.std.oid));
             hres = CO_E_OBJNOTCONNECTED;
         }
     }
     else
         TRACE("Treating unmarshal from OXID %s as inter-process\n",
-            wine_dbgstr_longlong(stdobjref.oxid));
+            wine_dbgstr_longlong(obj.std.oxid));
 
     if (hres == S_OK)
-        hres = unmarshal_object(&stdobjref, apt, This->dest_context,
-                                This->dest_context_data, riid,
+        hres = unmarshal_object(&obj.std, apt, dest_context,
+                                dest_context_data, riid,
                                 stubmgr ? &stubmgr->oxid_info : NULL, ppv);
 
     if (stubmgr) stub_manager_int_release(stubmgr);
@@ -1414,40 +1505,74 @@ StdMarshalImpl_UnmarshalInterface(IMarshal *iface, IStream *pStm, REFIID riid, v
 }
 
 static HRESULT WINAPI
-StdMarshalImpl_ReleaseMarshalData(IMarshal *iface, IStream *pStm)
+StdMarshalImpl_UnmarshalInterface(IMarshal *iface, IStream *pStm, REFIID riid, void **ppv)
 {
-    STDOBJREF            stdobjref;
+    StdMarshalImpl *This = impl_from_StdMarshal(iface);
+    OBJREF objref;
+    HRESULT hr;
+    ULONG res;
+
+    hr = IStream_Read(pStm, &objref, FIELD_OFFSET(OBJREF, u_objref), &res);
+    if (hr != S_OK || (res != FIELD_OFFSET(OBJREF, u_objref)))
+    {
+        ERR("Failed to read common OBJREF header, 0x%08x\n", hr);
+        return STG_E_READFAULT;
+    }
+
+    if (objref.signature != OBJREF_SIGNATURE)
+    {
+        ERR("Bad OBJREF signature 0x%08x\n", objref.signature);
+        return RPC_E_INVALID_OBJREF;
+    }
+
+    if (!(objref.flags & OBJREF_STANDARD))
+    {
+        FIXME("unsupported objref.flags = %x\n", objref.flags);
+        return E_NOTIMPL;
+    }
+
+    return std_unmarshal_interface(This->dest_context,
+            This->dest_context_data, pStm, riid, ppv);
+}
+
+static HRESULT std_release_marshal_data(IStream *pStm)
+{
+    struct OR_STANDARD   obj;
     ULONG                res;
     HRESULT              hres;
     struct stub_manager *stubmgr;
     APARTMENT           *apt;
 
-    TRACE("iface=%p, pStm=%p\n", iface, pStm);
-    
-    hres = IStream_Read(pStm, &stdobjref, sizeof(stdobjref), &res);
+    hres = IStream_Read(pStm, &obj, FIELD_OFFSET(struct OR_STANDARD, saResAddr.aStringArray), &res);
     if (hres != S_OK) return STG_E_READFAULT;
 
+    if (obj.saResAddr.wNumEntries)
+    {
+        ERR("unsupported size of DUALSTRINGARRAY\n");
+        return E_NOTIMPL;
+    }
+
     TRACE("oxid = %s, oid = %s, ipid = %s\n",
-        wine_dbgstr_longlong(stdobjref.oxid),
-        wine_dbgstr_longlong(stdobjref.oid),
-        wine_dbgstr_guid(&stdobjref.ipid));
+        wine_dbgstr_longlong(obj.std.oxid),
+        wine_dbgstr_longlong(obj.std.oid),
+        wine_dbgstr_guid(&obj.std.ipid));
 
-    if (!(apt = apartment_findfromoxid(stdobjref.oxid, TRUE)))
+    if (!(apt = apartment_findfromoxid(obj.std.oxid, TRUE)))
     {
         WARN("Could not map OXID %s to apartment object\n",
-            wine_dbgstr_longlong(stdobjref.oxid));
+            wine_dbgstr_longlong(obj.std.oxid));
         return RPC_E_INVALID_OBJREF;
     }
 
-    if (!(stubmgr = get_stub_manager(apt, stdobjref.oid)))
+    if (!(stubmgr = get_stub_manager(apt, obj.std.oid)))
     {
         apartment_release(apt);
         ERR("could not map object ID to stub manager, oxid=%s, oid=%s\n",
-            wine_dbgstr_longlong(stdobjref.oxid), wine_dbgstr_longlong(stdobjref.oid));
+            wine_dbgstr_longlong(obj.std.oxid), wine_dbgstr_longlong(obj.std.oid));
         return RPC_E_INVALID_OBJREF;
     }
 
-    stub_manager_release_marshal_data(stubmgr, stdobjref.cPublicRefs, &stdobjref.ipid, stdobjref.flags & SORFP_TABLEWEAK);
+    stub_manager_release_marshal_data(stubmgr, obj.std.cPublicRefs, &obj.std.ipid, obj.std.flags & SORFP_TABLEWEAK);
 
     stub_manager_int_release(stubmgr);
     apartment_release(apt);
@@ -1455,6 +1580,37 @@ StdMarshalImpl_ReleaseMarshalData(IMarshal *iface, IStream *pStm)
     return S_OK;
 }
 
+static HRESULT WINAPI
+StdMarshalImpl_ReleaseMarshalData(IMarshal *iface, IStream *pStm)
+{
+    OBJREF objref;
+    HRESULT hr;
+    ULONG res;
+
+    TRACE("iface=%p, pStm=%p\n", iface, pStm);
+
+    hr = IStream_Read(pStm, &objref, FIELD_OFFSET(OBJREF, u_objref), &res);
+    if (hr != S_OK || (res != FIELD_OFFSET(OBJREF, u_objref)))
+    {
+        ERR("Failed to read common OBJREF header, 0x%08x\n", hr);
+        return STG_E_READFAULT;
+    }
+
+    if (objref.signature != OBJREF_SIGNATURE)
+    {
+        ERR("Bad OBJREF signature 0x%08x\n", objref.signature);
+        return RPC_E_INVALID_OBJREF;
+    }
+
+    if (!(objref.flags & OBJREF_STANDARD))
+    {
+        FIXME("unsupported objref.flags = %x\n", objref.flags);
+        return E_NOTIMPL;
+    }
+
+    return std_release_marshal_data(pStm);
+}
+
 static HRESULT WINAPI
 StdMarshalImpl_DisconnectObject(IMarshal *iface, DWORD dwReserved)
 {
@@ -1588,7 +1744,8 @@ static HRESULT get_unmarshaler_from_stream(IStream *stream, IMarshal **marshal,
     if (objref.flags & OBJREF_STANDARD)
     {
         TRACE("Using standard unmarshaling\n");
-        hr = StdMarshalImpl_Construct(&IID_IMarshal, 0, NULL, (LPVOID*)marshal);
+        *marshal = NULL;
+        return S_FALSE;
     }
     else if (objref.flags & OBJREF_CUSTOM)
     {
@@ -1647,29 +1804,25 @@ HRESULT WINAPI CoGetMarshalSizeMax(ULONG *pulSize, REFIID riid, IUnknown *pUnk,
 {
     HRESULT hr;
     LPMARSHAL pMarshal;
-    CLSID marshaler_clsid;
+    BOOL std_marshal = FALSE;
 
-    hr = get_marshaler(riid, pUnk, dwDestContext, pvDestContext, mshlFlags, &pMarshal);
-    if (hr != S_OK)
-        return hr;
+    if(!pUnk)
+        return E_POINTER;
 
-    hr = IMarshal_GetUnmarshalClass(pMarshal, riid, pUnk, dwDestContext,
-                                    pvDestContext, mshlFlags, &marshaler_clsid);
+    hr = IUnknown_QueryInterface(pUnk, &IID_IMarshal, (void**)&pMarshal);
     if (hr != S_OK)
     {
-        ERR("IMarshal::GetUnmarshalClass failed, 0x%08x\n", hr);
-        IMarshal_Release(pMarshal);
-        return hr;
+        std_marshal = TRUE;
+        hr = CoGetStandardMarshal(riid, pUnk, dwDestContext, pvDestContext,
+                                  mshlFlags, &pMarshal);
     }
+    if (hr != S_OK)
+        return hr;
 
     hr = IMarshal_GetMarshalSizeMax(pMarshal, riid, pUnk, dwDestContext,
                                     pvDestContext, mshlFlags, pulSize);
-    if (IsEqualCLSID(&marshaler_clsid, &CLSID_DfMarshal))
-        /* add on the size of the common header */
-        *pulSize += FIELD_OFFSET(OBJREF, u_objref);
-    else
-        /* custom marshaling: add on the size of the whole OBJREF structure
-         * like native does */
+    if (!std_marshal)
+        /* add on the size of the whole OBJREF structure like native does */
         *pulSize += sizeof(OBJREF);
 
     IMarshal_Release(pMarshal);
@@ -1727,7 +1880,6 @@ HRESULT WINAPI CoMarshalInterface(IStream *pStream, REFIID riid, IUnknown *pUnk,
 {
     HRESULT    hr;
     CLSID marshaler_clsid;
-    OBJREF objref;
     LPMARSHAL pMarshal;
 
     TRACE("(%p, %s, %p, %x, %p, ", pStream, debugstr_guid(riid), pUnk,
@@ -1738,9 +1890,6 @@ HRESULT WINAPI CoMarshalInterface(IStream *pStream, REFIID riid, IUnknown *pUnk,
     if (!pUnk || !pStream)
         return E_INVALIDARG;
 
-    objref.signature = OBJREF_SIGNATURE;
-    objref.iid = *riid;
-
     /* get the marshaler for the specified interface */
     hr = get_marshaler(riid, pUnk, dwDestContext, pvDestContext, mshlFlags, &pMarshal);
     if (hr != S_OK)
@@ -1758,22 +1907,17 @@ HRESULT WINAPI CoMarshalInterface(IStream *pStream, REFIID riid, IUnknown *pUnk,
     }
 
     /* FIXME: implement handler marshaling too */
-    if (IsEqualCLSID(&marshaler_clsid, &CLSID_DfMarshal))
+    if (IsEqualCLSID(&marshaler_clsid, &CLSID_StdMarshal))
     {
         TRACE("Using standard marshaling\n");
-        objref.flags = OBJREF_STANDARD;
-
-        /* write the common OBJREF header to the stream */
-        hr = IStream_Write(pStream, &objref, FIELD_OFFSET(OBJREF, u_objref), NULL);
-        if (hr != S_OK)
-        {
-            ERR("Failed to write OBJREF header to stream, 0x%08x\n", hr);
-            goto cleanup;
-        }
     }
     else
     {
+        OBJREF objref;
+
         TRACE("Using custom marshaling\n");
+        objref.signature = OBJREF_SIGNATURE;
+        objref.iid = *riid;
         objref.flags = OBJREF_CUSTOM;
         objref.u_objref.u_custom.clsid = marshaler_clsid;
         objref.u_objref.u_custom.cbExtension = 0;
@@ -1848,13 +1992,20 @@ HRESULT WINAPI CoUnmarshalInterface(IStream *pStream, REFIID riid, LPVOID *ppv)
         return E_INVALIDARG;
 
     hr = get_unmarshaler_from_stream(pStream, &pMarshal, &iid);
-    if (hr != S_OK)
-        return hr;
-
-    /* call the helper object to do the actual unmarshaling */
-    hr = IMarshal_UnmarshalInterface(pMarshal, pStream, &iid, (LPVOID*)&object);
-    if (hr != S_OK)
-        ERR("IMarshal::UnmarshalInterface failed, 0x%08x\n", hr);
+    if (hr == S_FALSE)
+    {
+        hr = std_unmarshal_interface(0, NULL, pStream, &iid, (void**)&object);
+        if (hr != S_OK)
+            ERR("StdMarshal UnmarshalInterface failed, 0x%08x\n", hr);
+    }
+    else if (hr == S_OK)
+    {
+        /* call the helper object to do the actual unmarshaling */
+        hr = IMarshal_UnmarshalInterface(pMarshal, pStream, &iid, (LPVOID*)&object);
+        IMarshal_Release(pMarshal);
+        if (hr != S_OK)
+            ERR("IMarshal::UnmarshalInterface failed, 0x%08x\n", hr);
+    }
 
     if (hr == S_OK)
     {
@@ -1874,8 +2025,6 @@ HRESULT WINAPI CoUnmarshalInterface(IStream *pStream, REFIID riid, LPVOID *ppv)
         }
     }
 
-    IMarshal_Release(pMarshal);
-
     TRACE("completed with hr 0x%x\n", hr);
     
     return hr;
@@ -1912,6 +2061,13 @@ HRESULT WINAPI CoReleaseMarshalData(IStream *pStream)
     TRACE("(%p)\n", pStream);
 
     hr = get_unmarshaler_from_stream(pStream, &pMarshal, NULL);
+    if (hr == S_FALSE)
+    {
+        hr = std_release_marshal_data(pStream);
+        if (hr != S_OK)
+            ERR("StdMarshal ReleaseMarshalData failed with error 0x%08x\n", hr);
+        return hr;
+    }
     if (hr != S_OK)
         return hr;
 
index ffbaa61..c1312d1 100644 (file)
@@ -1152,7 +1152,7 @@ HRESULT WINAPI MkParseDisplayName(LPBC pbc, LPCOLESTR szDisplayName,
     *pchEaten = 0;
     *ppmk = NULL;
 
-    if (!strncmpiW(szDisplayName, wszClsidColon, sizeof(wszClsidColon)/sizeof(wszClsidColon[0])))
+    if (!strncmpiW(szDisplayName, wszClsidColon, ARRAY_SIZE(wszClsidColon)))
     {
         hr = ClassMoniker_CreateFromDisplayName(pbc, szDisplayName, &chEaten, &moniker);
         if (FAILED(hr) && (hr != MK_E_SYNTAX))
index c7a9b27..2de9edb 100644 (file)
@@ -967,7 +967,7 @@ static HRESULT WINAPI EnumOLEVERB_Next(
         LPWSTR pwszOLEVERB;
         LPWSTR pwszMenuFlags;
         LPWSTR pwszAttribs;
-        LONG res = RegEnumKeyW(This->hkeyVerb, This->index, wszSubKey, sizeof(wszSubKey)/sizeof(wszSubKey[0]));
+        LONG res = RegEnumKeyW(This->hkeyVerb, This->index, wszSubKey, ARRAY_SIZE(wszSubKey));
         if (res == ERROR_NO_MORE_ITEMS)
         {
             hr = S_FALSE;
index ccf31fa..e3820b9 100644 (file)
@@ -135,7 +135,7 @@ static HRESULT get_storage(IDataObject *data, IStorage *stg, UINT *src_cf, BOOL
 
     if (other_fmts)
     {
-        for (i = 0; i < sizeof(fmt_id)/sizeof(fmt_id[0]); i++)
+        for (i = 0; i < ARRAY_SIZE(fmt_id); i++)
         {
             init_fmtetc(&fmt, fmt_id[i], TYMED_ISTORAGE);
             hr = IDataObject_QueryGetData(data, &fmt);
@@ -232,9 +232,102 @@ HRESULT WINAPI OleCreateStaticFromData(IDataObject *data, REFIID iid,
                                        IOleClientSite *client_site, IStorage *stg,
                                        void **obj)
 {
-    FIXME("%p,%s,%08x,%p,%p,%p,%p: semi-stub\n",
+    HRESULT hr;
+    CLSID clsid;
+    IOleObject * ole_object = NULL;
+    IOleCache2 *ole_cache = NULL;
+    IPersistStorage *persist = NULL;
+    DWORD connection;
+    STGMEDIUM stgmedium;
+    LPOLESTR ole_typename;
+
+    TRACE("(%p, %s, 0x%08x, %p, %p, %p, %p)\n",
           data, debugstr_guid(iid), renderopt, fmt, client_site, stg, obj);
-    return OleCreateFromData(data, iid, renderopt, fmt, client_site, stg, obj);
+
+    if (!obj || !stg)
+        return E_INVALIDARG;
+
+    if (renderopt != OLERENDER_FORMAT)
+    {
+        FIXME("semi-stub\n");
+        return OleCreateFromData(data, iid, renderopt, fmt, client_site, stg, obj);
+    }
+
+    if (!fmt)
+        return E_INVALIDARG;
+
+    hr = IDataObject_GetData(data, fmt, &stgmedium);
+    if (FAILED(hr)) return hr;
+
+    switch (fmt->cfFormat)
+    {
+        case CF_BITMAP:
+        case CF_DIB:
+            clsid = CLSID_Picture_Dib;
+            break;
+        case CF_ENHMETAFILE:
+            clsid = CLSID_Picture_EnhMetafile;
+            break;
+        case CF_METAFILEPICT:
+            clsid = CLSID_Picture_Metafile;
+            break;
+        default:
+            ReleaseStgMedium(&stgmedium);
+            return DV_E_CLIPFORMAT;
+    }
+    hr = OleCreateDefaultHandler(&clsid, NULL, &IID_IOleObject, (void **)&ole_object);
+    if (FAILED(hr)) goto end;
+
+    if (client_site)
+    {
+        hr = IOleObject_SetClientSite(ole_object, client_site);
+        if (FAILED(hr)) goto end;
+    }
+
+    hr = IOleObject_QueryInterface(ole_object, &IID_IOleCache2, (void **)&ole_cache);
+    if (FAILED(hr)) goto end;
+
+    hr = IOleObject_QueryInterface(ole_object, &IID_IPersistStorage, (void **)&persist);
+    if (FAILED(hr)) goto end;
+
+    hr = WriteClassStg(stg, &clsid);
+    if (FAILED(hr)) goto end;
+
+    hr = IPersistStorage_InitNew(persist, stg);
+    if (FAILED(hr)) goto end;
+
+    hr = IOleCache2_Cache(ole_cache, fmt, ADVF_PRIMEFIRST, &connection);
+    if (FAILED(hr)) goto end;
+
+    hr = IOleCache2_SetData(ole_cache, fmt, &stgmedium, TRUE);
+    if (FAILED(hr)) goto end;
+    stgmedium.tymed = TYMED_NULL;
+
+    hr = IOleObject_GetUserType(ole_object, USERCLASSTYPE_FULL, &ole_typename);
+    if(FAILED(hr))
+        ole_typename = NULL;
+    hr = WriteFmtUserTypeStg(stg, fmt->cfFormat, ole_typename);
+    CoTaskMemFree(ole_typename);
+    if (FAILED(hr)) goto end;
+
+    hr = IPersistStorage_Save(persist, stg, TRUE);
+    if (FAILED(hr)) goto end;
+
+    hr = IPersistStorage_SaveCompleted(persist, NULL);
+    if (FAILED(hr)) goto end;
+
+    hr = IOleObject_QueryInterface(ole_object, iid, obj);
+
+end:
+    if (stgmedium.tymed == TYMED_NULL)
+        ReleaseStgMedium(&stgmedium);
+    if (persist)
+        IPersistStorage_Release(persist);
+    if (ole_cache)
+        IOleCache2_Release(ole_cache);
+    if (ole_object)
+        IOleObject_Release(ole_object);
+    return hr;
 }
 
 /******************************************************************************
index a73d23c..bd4611d 100644 (file)
@@ -109,6 +109,7 @@ typedef struct
     OXID                   oxid; /* apartment in which the channel is valid */
     DWORD                  server_pid; /* id of server process */
     HANDLE                 event; /* cached event handle */
+    IID                    iid; /* IID of the proxy this belongs to */
 } ClientRpcChannelBuffer;
 
 struct dispatch_params
@@ -650,7 +651,7 @@ static HRESULT WINAPI ClientRpcChannelBuffer_GetBuffer(LPRPCCHANNELBUFFER iface,
 
     cif->Length = sizeof(RPC_CLIENT_INTERFACE);
     /* RPC interface ID = COM interface ID */
-    cif->InterfaceId.SyntaxGUID = *riid;
+    cif->InterfaceId.SyntaxGUID = This->iid;
     /* COM objects always have a version of 0.0 */
     cif->InterfaceId.SyntaxVersion.MajorVersion = 0;
     cif->InterfaceId.SyntaxVersion.MinorVersion = 0;
@@ -1096,7 +1097,7 @@ static const IRpcChannelBufferVtbl ServerRpcChannelBufferVtbl =
 
 /* returns a channel buffer for proxies */
 HRESULT RPC_CreateClientChannel(const OXID *oxid, const IPID *ipid,
-                                const OXID_INFO *oxid_info,
+                                const OXID_INFO *oxid_info, const IID *iid,
                                 DWORD dest_context, void *dest_context_data,
                                 IRpcChannelBuffer **chan, APARTMENT *apt)
 {
@@ -1155,6 +1156,7 @@ HRESULT RPC_CreateClientChannel(const OXID *oxid, const IPID *ipid,
     apartment_getoxid(apt, &This->oxid);
     This->server_pid = oxid_info->dwPid;
     This->event = NULL;
+    This->iid = *iid;
 
     *chan = &This->super.IRpcChannelBuffer_iface;
 
@@ -1658,7 +1660,7 @@ static HRESULT create_server(REFCLSID rclsid, HANDLE *process)
     static const WCHAR  embedding[] = { ' ', '-','E','m','b','e','d','d','i','n','g',0 };
     HKEY                key;
     HRESULT             hres;
-    WCHAR               command[MAX_PATH+sizeof(embedding)/sizeof(WCHAR)];
+    WCHAR               command[MAX_PATH+ARRAY_SIZE(embedding)];
     DWORD               size = (MAX_PATH+1) * sizeof(WCHAR);
     STARTUPINFOW        sinfo;
     PROCESS_INFORMATION pinfo;
@@ -1799,7 +1801,7 @@ static void get_localserver_pipe_name(WCHAR *pipefn, REFCLSID rclsid)
 {
     static const WCHAR wszPipeRef[] = {'\\','\\','.','\\','p','i','p','e','\\',0};
     strcpyW(pipefn, wszPipeRef);
-    StringFromGUID2(rclsid, pipefn + sizeof(wszPipeRef)/sizeof(wszPipeRef[0]) - 1, CHARS_IN_GUID);
+    StringFromGUID2(rclsid, pipefn + ARRAY_SIZE(wszPipeRef) - 1, CHARS_IN_GUID);
 }
 
 /* FIXME: should call to rpcss instead */
index 1d5e034..4b968d6 100644 (file)
@@ -1058,11 +1058,13 @@ static HRESULT PropertyStorage_ReadProperty(PROPVARIANT *prop, const BYTE *data,
     UINT codepage, void* (__thiscall_wrapper *allocate)(void *this, ULONG size), void *allocate_data)
 {
     HRESULT hr = S_OK;
+    DWORD vt;
 
     assert(prop);
     assert(data);
-    StorageUtl_ReadDWord(data, 0, (DWORD *)&prop->vt);
+    StorageUtl_ReadDWord(data, 0, &vt);
     data += sizeof(DWORD);
+    prop->vt = vt;
     switch (prop->vt)
     {
     case VT_EMPTY:
index 51f178b..a8bbd40 100644 (file)
@@ -5057,7 +5057,7 @@ static HRESULT StorageImpl_LockOne(StorageImpl *This, ULONG start, ULONG end)
 
     if (SUCCEEDED(hr))
     {
-        for (j=0; j<sizeof(This->locked_bytes)/sizeof(This->locked_bytes[0]); j++)
+        for (j = 0; j < ARRAY_SIZE(This->locked_bytes); j++)
         {
             if (This->locked_bytes[j] == 0)
             {
@@ -5200,10 +5200,10 @@ static void StorageImpl_Destroy(StorageBaseImpl* iface)
   BlockChainStream_Destroy(This->rootBlockChain);
   BlockChainStream_Destroy(This->smallBlockDepotChain);
 
-  for (i=0; i<BLOCKCHAIN_CACHE_SIZE; i++)
+  for (i = 0; i < BLOCKCHAIN_CACHE_SIZE; i++)
     BlockChainStream_Destroy(This->blockChainCache[i]);
 
-  for (i=0; i<sizeof(This->locked_bytes)/sizeof(This->locked_bytes[0]); i++)
+  for (i = 0; i < ARRAY_SIZE(This->locked_bytes); i++)
   {
     ULARGE_INTEGER offset, cb;
     cb.QuadPart = 1;
@@ -9369,8 +9369,7 @@ HRESULT WINAPI WriteFmtUserTypeStg(
     /* get the clipboard format name */
     if( cf )
     {
-        n = GetClipboardFormatNameW( cf, szwClipName,
-                sizeof(szwClipName)/sizeof(szwClipName[0]) );
+        n = GetClipboardFormatNameW(cf, szwClipName, ARRAY_SIZE(szwClipName));
         szwClipName[n]=0;
     }
 
@@ -10035,8 +10034,8 @@ HRESULT OLECONVERT_CreateCompObjStream(LPSTORAGE pStorage, LPCSTR strOleTypeName
     static const WCHAR wstrStreamName[] = {1,'C', 'o', 'm', 'p', 'O', 'b', 'j', 0};
     WCHAR bufferW[OLESTREAM_MAX_STR_LEN];
 
-    BYTE pCompObjUnknown1[] = {0x01, 0x00, 0xFE, 0xFF, 0x03, 0x0A, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF};
-    BYTE pCompObjUnknown2[] = {0xF4, 0x39, 0xB2, 0x71};
+    static const BYTE pCompObjUnknown1[] = {0x01, 0x00, 0xFE, 0xFF, 0x03, 0x0A, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF};
+    static const BYTE pCompObjUnknown2[] = {0xF4, 0x39, 0xB2, 0x71};
 
     /* Initialize the CompObj structure */
     memset(&IStorageCompObj, 0, sizeof(IStorageCompObj));
@@ -10134,7 +10133,7 @@ static void OLECONVERT_CreateOlePresStream(LPSTORAGE pStorage, DWORD dwExtentX,
     HRESULT hRes;
     IStream *pStream;
     static const WCHAR wstrStreamName[] = {2, 'O', 'l', 'e', 'P', 'r', 'e', 's', '0', '0', '0', 0};
-    BYTE pOlePresStreamHeader [] =
+    static const BYTE pOlePresStreamHeader[] =
     {
         0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00,
         0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
@@ -10142,7 +10141,7 @@ static void OLECONVERT_CreateOlePresStream(LPSTORAGE pStorage, DWORD dwExtentX,
         0x00, 0x00, 0x00, 0x00
     };
 
-    BYTE pOlePresStreamHeaderEmpty [] =
+    static const BYTE pOlePresStreamHeaderEmpty[] =
     {
         0x00, 0x00, 0x00, 0x00,
         0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
index 3d1284a..9f19b66 100644 (file)
@@ -116,7 +116,7 @@ ULONG __RPC_USER CLIPFORMAT_UserSize(ULONG *pFlags, ULONG size, CLIPFORMAT *pCF)
         /* urg! this function is badly designed because it won't tell us how
          * much space is needed without doing a dummy run of storing the
          * name into a buffer */
-        ret = GetClipboardFormatNameW(*pCF, format, sizeof(format)/sizeof(format[0])-1);
+        ret = GetClipboardFormatNameW(*pCF, format, ARRAY_SIZE(format)-1);
         if (!ret)
             RaiseException(DV_E_CLIPFORMAT, 0, 0, NULL);
         size += (ret + 1) * sizeof(WCHAR);
@@ -161,7 +161,7 @@ unsigned char * __RPC_USER CLIPFORMAT_UserMarshal(ULONG *pFlags, unsigned char *
         *(DWORD *)pBuffer = *pCF;
         pBuffer += 4;
 
-        len = GetClipboardFormatNameW(*pCF, format, sizeof(format)/sizeof(format[0])-1);
+        len = GetClipboardFormatNameW(*pCF, format, ARRAY_SIZE(format)-1);
         if (!len)
             RaiseException(DV_E_CLIPFORMAT, 0, 0, NULL);
         len += 1;
index 7b4141c..5313ce6 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-4.0. Depends on port of Linux ODBC.
 reactos/dll/win32/odbccp32            # Synced to WineStaging-4.0
-reactos/dll/win32/ole32               # Synced to WineStaging-3.9
+reactos/dll/win32/ole32               # Synced to WineStaging-4.0
 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