urlmon: Added user marshaling implementation for GetBindInfo[Ex].
[wine.git] / dlls / urlmon / usrmarshal.c
blob9ddb130646f587253fba72ab8c00905d6c5719b1
1 /*
2 * Copyright 2009 Piotr Caban for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 #define NONAMELESSUNION
21 #include "urlmon_main.h"
23 #include "wine/debug.h"
25 WINE_DEFAULT_DEBUG_CHANNEL(urlmon);
27 HRESULT CALLBACK IWinInetHttpInfo_QueryInfo_Proxy(IWinInetHttpInfo* This,
28 DWORD dwOption, LPVOID pBuffer, DWORD *pcbBuf, DWORD *pdwFlags,
29 DWORD *pdwReserved)
31 TRACE("(%p %x %p %p %p %p)\n", This, dwOption, pBuffer, pcbBuf, pdwFlags, pdwReserved);
32 return IWinInetHttpInfo_RemoteQueryInfo_Proxy(This, dwOption, pBuffer, pcbBuf, pdwFlags, pdwReserved);
35 HRESULT __RPC_STUB IWinInetHttpInfo_QueryInfo_Stub(IWinInetHttpInfo* This,
36 DWORD dwOption, BYTE *pBuffer, DWORD *pcbBuf, DWORD *pdwFlags,
37 DWORD *pdwReserved)
39 TRACE("(%p %x %p %p %p %p)\n", This, dwOption, pBuffer, pcbBuf, pdwFlags, pdwReserved);
40 return IWinInetHttpInfo_QueryInfo(This, dwOption, pBuffer, pcbBuf, pdwFlags, pdwReserved);
43 HRESULT CALLBACK IWinInetInfo_QueryOption_Proxy(IWinInetInfo* This,
44 DWORD dwOption, LPVOID pBuffer, DWORD *pcbBuf)
46 TRACE("(%p %x %p %p)\n", This, dwOption, pBuffer, pcbBuf);
47 return IWinInetInfo_RemoteQueryOption_Proxy(This, dwOption, pBuffer, pcbBuf);
50 HRESULT __RPC_STUB IWinInetInfo_QueryOption_Stub(IWinInetInfo* This,
51 DWORD dwOption, BYTE *pBuffer, DWORD *pcbBuf)
53 TRACE("(%p %x %p %p)\n", This, dwOption, pBuffer, pcbBuf);
54 return IWinInetInfo_QueryOption(This, dwOption, pBuffer, pcbBuf);
57 HRESULT CALLBACK IBindHost_MonikerBindToStorage_Proxy(IBindHost* This,
58 IMoniker *moniker, IBindCtx *bc, IBindStatusCallback *bsc,
59 REFIID riid, void **obj)
61 TRACE("(%p %p %p %p %s %p)\n", This, moniker, bc, bsc, debugstr_guid(riid), obj);
62 return IBindHost_RemoteMonikerBindToStorage_Proxy(This, moniker, bc, bsc, riid, (IUnknown**)obj);
65 HRESULT __RPC_STUB IBindHost_MonikerBindToStorage_Stub(IBindHost* This,
66 IMoniker *moniker, IBindCtx *bc, IBindStatusCallback *bsc,
67 REFIID riid, IUnknown **obj)
69 TRACE("(%p %p %p %p %s %p)\n", This, moniker, bc, bsc, debugstr_guid(riid), obj);
70 return IBindHost_MonikerBindToStorage(This, moniker, bc, bsc, riid, (void**)obj);
73 HRESULT CALLBACK IBindHost_MonikerBindToObject_Proxy(IBindHost* This,
74 IMoniker *moniker, IBindCtx *bc, IBindStatusCallback *bsc,
75 REFIID riid, void **obj)
77 TRACE("(%p %p %p %p %s %p)\n", This, moniker, bc, bsc, debugstr_guid(riid), obj);
78 return IBindHost_RemoteMonikerBindToObject_Proxy(This, moniker, bc, bsc, riid, (IUnknown**)obj);
81 HRESULT __RPC_STUB IBindHost_MonikerBindToObject_Stub(IBindHost* This,
82 IMoniker *moniker, IBindCtx *bc, IBindStatusCallback *bsc,
83 REFIID riid, IUnknown **obj)
85 TRACE("(%p %p %p %p %s %p)\n", This, moniker, bc, bsc, debugstr_guid(riid), obj);
86 return IBindHost_MonikerBindToObject(This, moniker, bc, bsc, riid, (void**)obj);
89 static HRESULT marshal_stgmed(STGMEDIUM *stgmed, RemSTGMEDIUM **ret)
91 RemSTGMEDIUM *rem_stgmed;
92 IStream *stream = NULL;
93 ULONG size = 0;
94 HRESULT hres = S_OK;
96 if((stgmed->tymed == TYMED_ISTREAM && stgmed->u.pstm) || stgmed->pUnkForRelease) {
97 hres = CreateStreamOnHGlobal(NULL, TRUE, &stream);
98 if(FAILED(hres))
99 return hres;
102 switch(stgmed->tymed) {
103 case TYMED_NULL:
104 break;
105 case TYMED_ISTREAM:
106 if(stgmed->u.pstm)
107 hres = CoMarshalInterface(stream, &IID_IStream, (IUnknown*)stgmed->u.pstm,
108 MSHCTX_LOCAL, NULL, MSHLFLAGS_NORMAL);
109 break;
110 default:
111 FIXME("unsupported tymed %u\n", stgmed->tymed);
112 break;
115 if(SUCCEEDED(hres) && stgmed->pUnkForRelease)
116 hres = CoMarshalInterface(stream, &IID_IUnknown, stgmed->pUnkForRelease,
117 MSHCTX_LOCAL, NULL, MSHLFLAGS_NORMAL);
118 if(FAILED(hres)) {
119 if(stream)
120 IStream_Release(stream);
121 return hres;
124 if(stream) {
125 LARGE_INTEGER zero;
126 ULARGE_INTEGER off;
128 zero.QuadPart = 0;
129 IStream_Seek(stream, zero, STREAM_SEEK_CUR, &off);
130 size = off.QuadPart;
131 IStream_Seek(stream, zero, STREAM_SEEK_SET, &off);
134 rem_stgmed = heap_alloc_zero(FIELD_OFFSET(RemSTGMEDIUM, data[size]));
135 if(!rem_stgmed) {
136 if(stream)
137 IStream_Release(stream);
138 return E_OUTOFMEMORY;
141 rem_stgmed->tymed = stgmed->tymed;
142 rem_stgmed->dwHandleType = 0;
143 rem_stgmed->pData = stgmed->u.pstm != NULL;
144 rem_stgmed->pUnkForRelease = stgmed->pUnkForRelease != NULL;
145 rem_stgmed->cbData = size;
146 if(stream) {
147 IStream_Read(stream, rem_stgmed->data, size, &size);
148 IStream_Release(stream);
151 *ret = rem_stgmed;
152 return S_OK;
155 static HRESULT unmarshal_stgmed(RemSTGMEDIUM *rem_stgmed, STGMEDIUM *stgmed)
157 IStream *stream = NULL;
158 HRESULT hres = S_OK;
160 stgmed->tymed = rem_stgmed->tymed;
162 if((stgmed->tymed == TYMED_ISTREAM && rem_stgmed->pData) || rem_stgmed->pUnkForRelease) {
163 LARGE_INTEGER zero;
165 hres = CreateStreamOnHGlobal(NULL, TRUE, &stream);
166 if(FAILED(hres))
167 return hres;
169 hres = IStream_Write(stream, rem_stgmed->data, rem_stgmed->cbData, NULL);
170 if(FAILED(hres)) {
171 IStream_Release(stream);
172 return hres;
175 zero.QuadPart = 0;
176 IStream_Seek(stream, zero, STREAM_SEEK_SET, NULL);
179 switch(stgmed->tymed) {
180 case TYMED_NULL:
181 break;
182 case TYMED_ISTREAM:
183 if(rem_stgmed->pData)
184 hres = CoUnmarshalInterface(stream, &IID_IStream, (void**)&stgmed->u.pstm);
185 break;
186 default:
187 FIXME("unsupported tymed %u\n", stgmed->tymed);
188 break;
191 if(SUCCEEDED(hres) && rem_stgmed->pUnkForRelease)
192 hres = CoUnmarshalInterface(stream, &IID_IUnknown, (void**)&stgmed->pUnkForRelease);
193 if(stream)
194 IStream_Release(stream);
195 return hres;
198 static void proxy_marshal_bindinfo(BINDINFO *bindinfo, RemBINDINFO *rem_bindinfo)
200 rem_bindinfo->szExtraInfo = bindinfo->szExtraInfo;
201 rem_bindinfo->grfBindInfoF = bindinfo->grfBindInfoF;
202 rem_bindinfo->dwBindVerb = bindinfo->dwBindVerb;
203 rem_bindinfo->szCustomVerb = bindinfo->szCustomVerb;
204 rem_bindinfo->cbstgmedData = bindinfo->cbstgmedData;
207 static void proxy_unmarshal_bindinfo(RemBINDINFO *rem_bindinfo, BINDINFO *bindinfo)
209 bindinfo->szExtraInfo = rem_bindinfo->szExtraInfo;
210 bindinfo->grfBindInfoF = rem_bindinfo->grfBindInfoF;
211 bindinfo->dwBindVerb = rem_bindinfo->dwBindVerb;
212 bindinfo->szCustomVerb = rem_bindinfo->szCustomVerb;
213 bindinfo->cbstgmedData = rem_bindinfo->cbstgmedData;
214 bindinfo->dwOptions = rem_bindinfo->dwOptions;
215 bindinfo->dwOptionsFlags = rem_bindinfo->dwOptionsFlags;
216 bindinfo->dwCodePage = rem_bindinfo->dwCodePage;
217 bindinfo->iid = IID_NULL;
218 bindinfo->pUnk = NULL;
221 static void stub_unmarshal_bindinfo(RemBINDINFO *rem_bindinfo, BINDINFO *bindinfo)
223 bindinfo->szExtraInfo = rem_bindinfo->szExtraInfo;
224 bindinfo->grfBindInfoF = rem_bindinfo->grfBindInfoF;
225 bindinfo->dwBindVerb = rem_bindinfo->dwBindVerb;
226 bindinfo->szCustomVerb = rem_bindinfo->szCustomVerb;
227 bindinfo->cbstgmedData = rem_bindinfo->cbstgmedData;
229 if(bindinfo->stgmedData.tymed != TYMED_NULL)
230 WARN("stgmed data (tymed %u) will be lost!\n", bindinfo->stgmedData.tymed);
233 static void stub_marshal_bindinfo(BINDINFO *bindinfo, RemBINDINFO *rem_bindinfo)
235 rem_bindinfo->cbSize = sizeof(*rem_bindinfo);
236 rem_bindinfo->szExtraInfo = bindinfo->szExtraInfo;
237 rem_bindinfo->grfBindInfoF = bindinfo->grfBindInfoF;
238 rem_bindinfo->dwBindVerb = bindinfo->dwBindVerb;
239 rem_bindinfo->szCustomVerb = bindinfo->szCustomVerb;
240 rem_bindinfo->cbstgmedData = bindinfo->cbstgmedData;
241 rem_bindinfo->dwOptions = bindinfo->dwOptions;
242 rem_bindinfo->dwOptionsFlags = bindinfo->dwOptionsFlags;
243 rem_bindinfo->dwCodePage = bindinfo->dwCodePage;
244 rem_bindinfo->pUnk = NULL;
245 rem_bindinfo->dwReserved = bindinfo->dwReserved;
249 HRESULT CALLBACK IBindStatusCallbackEx_GetBindInfoEx_Proxy(
250 IBindStatusCallbackEx* This, DWORD *grfBINDF, BINDINFO *bindinfo,
251 DWORD *grfBINDF2, DWORD *pdwReserved)
253 RemBINDINFO rem_bindinfo = {sizeof(rem_bindinfo)};
254 RemSTGMEDIUM rem_stgmed = {0};
255 HRESULT hres;
257 TRACE("(%p)->(%p %p %p %p)\n", This, grfBINDF, bindinfo, grfBINDF2, pdwReserved);
259 proxy_marshal_bindinfo(bindinfo, &rem_bindinfo);
260 hres = IBindStatusCallbackEx_RemoteGetBindInfoEx_Proxy(This, grfBINDF, &rem_bindinfo,
261 &rem_stgmed, grfBINDF2, pdwReserved);
262 proxy_unmarshal_bindinfo(&rem_bindinfo, bindinfo);
263 return hres;
266 HRESULT __RPC_STUB IBindStatusCallbackEx_GetBindInfoEx_Stub(
267 IBindStatusCallbackEx* This, DWORD *grfBINDF, RemBINDINFO *rem_bindinfo,
268 RemSTGMEDIUM *rem_stgmed, DWORD *grfBINDF2, DWORD *pdwReserved)
270 BINDINFO bindinfo = {sizeof(bindinfo)};
271 HRESULT hres;
273 TRACE("(%p)->(%p %p %p %p %p)\n", This, grfBINDF, rem_bindinfo, rem_stgmed, grfBINDF2, pdwReserved);
276 * Although arguments suggest support for STGMEDIUM from BINDINFO, tests show
277 * that it's not supported and returned data is lost.
279 stub_unmarshal_bindinfo(rem_bindinfo, &bindinfo);
280 hres = IBindStatusCallbackEx_GetBindInfoEx(This, grfBINDF, &bindinfo, grfBINDF2, pdwReserved);
281 stub_marshal_bindinfo(&bindinfo, rem_bindinfo);
282 return hres;
284 HRESULT CALLBACK IBindStatusCallback_GetBindInfo_Proxy(
285 IBindStatusCallback* This, DWORD *grfBINDF, BINDINFO *bindinfo)
287 RemBINDINFO rem_bindinfo = {sizeof(rem_bindinfo)};
288 RemSTGMEDIUM rem_stgmed = {0};
289 HRESULT hres;
291 TRACE("(%p)->(%p %p)\n", This, grfBINDF, bindinfo);
293 proxy_marshal_bindinfo(bindinfo, &rem_bindinfo);
294 hres = IBindStatusCallback_RemoteGetBindInfo_Proxy(This, grfBINDF, &rem_bindinfo, &rem_stgmed);
295 proxy_unmarshal_bindinfo(&rem_bindinfo, bindinfo);
296 return hres;
299 HRESULT __RPC_STUB IBindStatusCallback_GetBindInfo_Stub(
300 IBindStatusCallback* This, DWORD *grfBINDF,
301 RemBINDINFO *rem_bindinfo, RemSTGMEDIUM *rem_stgmed)
303 BINDINFO bindinfo = {sizeof(bindinfo)};
304 HRESULT hres;
306 TRACE("(%p)->(%p %p %p)\n", This, grfBINDF, rem_bindinfo, rem_stgmed);
308 stub_unmarshal_bindinfo(rem_bindinfo, &bindinfo);
309 hres = IBindStatusCallback_GetBindInfo(This, grfBINDF, &bindinfo);
310 stub_marshal_bindinfo(&bindinfo, rem_bindinfo);
311 return hres;
314 HRESULT CALLBACK IBindStatusCallback_OnDataAvailable_Proxy(
315 IBindStatusCallback* This, DWORD grfBSCF, DWORD dwSize,
316 FORMATETC *pformatetc, STGMEDIUM *pstgmed)
318 RemFORMATETC rem_formatetc;
319 RemSTGMEDIUM *rem_stgmed;
320 HRESULT hres;
322 TRACE("(%p)->(%x %u %p %p)\n", This, grfBSCF, dwSize, pformatetc, pstgmed);
324 hres = marshal_stgmed(pstgmed, &rem_stgmed);
325 if(FAILED(hres))
326 return hres;
328 rem_formatetc.cfFormat = pformatetc->cfFormat;
329 rem_formatetc.ptd = 0;
330 rem_formatetc.dwAspect = pformatetc->dwAspect;
331 rem_formatetc.lindex = pformatetc->lindex;
332 rem_formatetc.tymed = pformatetc->tymed;
334 hres = IBindStatusCallback_RemoteOnDataAvailable_Proxy(This, grfBSCF, dwSize, &rem_formatetc, rem_stgmed);
336 heap_free(rem_stgmed);
337 return hres;
340 HRESULT __RPC_STUB IBindStatusCallback_OnDataAvailable_Stub(
341 IBindStatusCallback* This, DWORD grfBSCF, DWORD dwSize,
342 RemFORMATETC *pformatetc, RemSTGMEDIUM *pstgmed)
344 STGMEDIUM stgmed = { TYMED_NULL };
345 FORMATETC formatetc;
346 HRESULT hres;
348 TRACE("(%p)->(%x %u %p %p)\n", This, grfBSCF, dwSize, pformatetc, pstgmed);
350 hres = unmarshal_stgmed(pstgmed, &stgmed);
351 if(FAILED(hres))
352 return hres;
354 formatetc.cfFormat = pformatetc->cfFormat;
355 formatetc.ptd = NULL;
356 formatetc.dwAspect = pformatetc->dwAspect;
357 formatetc.lindex = pformatetc->lindex;
358 formatetc.tymed = pformatetc->tymed;
360 hres = IBindStatusCallback_OnDataAvailable(This, grfBSCF, dwSize, &formatetc, &stgmed);
362 ReleaseStgMedium(&stgmed);
363 return hres;
366 HRESULT CALLBACK IBinding_GetBindResult_Proxy(IBinding* This,
367 CLSID *pclsidProtocol, DWORD *pdwResult,
368 LPOLESTR *pszResult, DWORD *pdwReserved)
370 FIXME("stub\n");
371 return E_NOTIMPL;
374 HRESULT __RPC_STUB IBinding_GetBindResult_Stub(IBinding* This,
375 CLSID *pclsidProtocol, DWORD *pdwResult,
376 LPOLESTR *pszResult, DWORD dwReserved)
378 FIXME("stub\n");
379 return E_NOTIMPL;