*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;
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);
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))
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;
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)
#include "ctxtcall.h"
#include "dde.h"
#include "servprov.h"
+
#ifndef __REACTOS__
#include "initguid.h"
#endif
WINE_DEFAULT_DEBUG_CHANNEL(ole);
-#undef ARRAYSIZE
-#define ARRAYSIZE(array) (sizeof(array)/sizeof((array)[0]))
-
/****************************************************************************
* This section defines variables internal to the COM module.
*/
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
*/
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;
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;
}
}
TRACE("clsid %s, iid %s\n", debugstr_guid(¶ms->clsid), debugstr_guid(¶ms->iid));
- if (COM_RegReadPath(¶ms->regdata, dllpath, ARRAYSIZE(dllpath)) != ERROR_SUCCESS)
+ if (!get_object_dll_path(¶ms->regdata, dllpath, ARRAY_SIZE(dllpath)))
{
/* failure: CLSID is not found in registry */
WARN("class %s not registered inproc\n", debugstr_guid(¶ms->clsid));
wclass.lpfnWndProc = apartment_wndproc;
wclass.hInstance = hProxyDll;
wclass.lpszClassName = wszAptWinClass;
- RegisterClassW(&wclass);
+ apt_win_class = RegisterClassW(&wclass);
return TRUE;
}
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;
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;
{
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;
/* 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 ||
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));
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;
regdata.u.hkey = hkey;
regdata.hkey = TRUE;
- if (COM_RegReadPath(®data, dllpath, ARRAYSIZE(dllpath)) == ERROR_SUCCESS)
+ if (get_object_dll_path(®data, dllpath, ARRAY_SIZE(dllpath)))
{
static const WCHAR wszOle32[] = {'o','l','e','3','2','.','d','l','l',0};
if (!strcmpiW(dllpath, wszOle32))
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);
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;
}
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 );
if (dwDestContext == MSHCTX_INPROC || dwDestContext == MSHCTX_CROSSCTX)
*pCid = CLSID_InProcFreeMarshaler;
else
- *pCid = CLSID_DfMarshal;
+ *pCid = CLSID_StdMarshal;
return S_OK;
}
/* 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);
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)
WINE_DEFAULT_DEBUG_CHANNEL(ole);
-extern const CLSID CLSID_DfMarshal;
-
/* number of refs given out for normal marshaling */
#define NORMALEXTREFS 5
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)
{
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)
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
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;
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)
IMarshal *iface, REFIID riid, void* pv, DWORD dwDestContext,
void* pvDestContext, DWORD mshlflags, CLSID* pCid)
{
- *pCid = CLSID_DfMarshal;
+ *pCid = CLSID_StdMarshal;
return S_OK;
}
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;
}
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));
/* 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)
{
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
{
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);
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;
}
/* 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);
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);
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);
* 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);
}
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);
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)
{
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)
{
{
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);
{
HRESULT hr;
CLSID marshaler_clsid;
- OBJREF objref;
LPMARSHAL pMarshal;
TRACE("(%p, %s, %p, %x, %p, ", pStream, debugstr_guid(riid), 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)
}
/* 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;
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)
{
}
}
- IMarshal_Release(pMarshal);
-
TRACE("completed with hr 0x%x\n", hr);
return hr;
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;
*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))
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;
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);
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;
}
/******************************************************************************
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
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;
/* 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)
{
apartment_getoxid(apt, &This->oxid);
This->server_pid = oxid_info->dwPid;
This->event = NULL;
+ This->iid = *iid;
*chan = &This->super.IRpcChannelBuffer_iface;
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;
{
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 */
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:
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)
{
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;
/* 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;
}
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));
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,
0x00, 0x00, 0x00, 0x00
};
- BYTE pOlePresStreamHeaderEmpty [] =
+ static const BYTE pOlePresStreamHeaderEmpty[] =
{
0x00, 0x00, 0x00, 0x00,
0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
/* 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);
*(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;
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