[URLMON] Sync with Wine 3.0. CORE-14225
[reactos.git] / dll / win32 / urlmon / usrmarshal.c
1 /*
2 * Copyright 2009 Piotr Caban for CodeWeavers
3 *
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.
8 *
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.
13 *
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
17 */
18
19 #include "urlmon_main.h"
20
21 #include <ole2.h>
22
23 HRESULT CALLBACK IWinInetHttpInfo_QueryInfo_Proxy(IWinInetHttpInfo* This,
24 DWORD dwOption, LPVOID pBuffer, DWORD *pcbBuf, DWORD *pdwFlags,
25 DWORD *pdwReserved)
26 {
27 TRACE("(%p %x %p %p %p %p)\n", This, dwOption, pBuffer, pcbBuf, pdwFlags, pdwReserved);
28 return IWinInetHttpInfo_RemoteQueryInfo_Proxy(This, dwOption, pBuffer, pcbBuf, pdwFlags, pdwReserved);
29 }
30
31 HRESULT __RPC_STUB IWinInetHttpInfo_QueryInfo_Stub(IWinInetHttpInfo* This,
32 DWORD dwOption, BYTE *pBuffer, DWORD *pcbBuf, DWORD *pdwFlags,
33 DWORD *pdwReserved)
34 {
35 TRACE("(%p %x %p %p %p %p)\n", This, dwOption, pBuffer, pcbBuf, pdwFlags, pdwReserved);
36 return IWinInetHttpInfo_QueryInfo(This, dwOption, pBuffer, pcbBuf, pdwFlags, pdwReserved);
37 }
38
39 HRESULT CALLBACK IWinInetInfo_QueryOption_Proxy(IWinInetInfo* This,
40 DWORD dwOption, LPVOID pBuffer, DWORD *pcbBuf)
41 {
42 TRACE("(%p %x %p %p)\n", This, dwOption, pBuffer, pcbBuf);
43 return IWinInetInfo_RemoteQueryOption_Proxy(This, dwOption, pBuffer, pcbBuf);
44 }
45
46 HRESULT __RPC_STUB IWinInetInfo_QueryOption_Stub(IWinInetInfo* This,
47 DWORD dwOption, BYTE *pBuffer, DWORD *pcbBuf)
48 {
49 TRACE("(%p %x %p %p)\n", This, dwOption, pBuffer, pcbBuf);
50 return IWinInetInfo_QueryOption(This, dwOption, pBuffer, pcbBuf);
51 }
52
53 HRESULT CALLBACK IBindHost_MonikerBindToStorage_Proxy(IBindHost* This,
54 IMoniker *moniker, IBindCtx *bc, IBindStatusCallback *bsc,
55 REFIID riid, void **obj)
56 {
57 TRACE("(%p %p %p %p %s %p)\n", This, moniker, bc, bsc, debugstr_guid(riid), obj);
58 return IBindHost_RemoteMonikerBindToStorage_Proxy(This, moniker, bc, bsc, riid, (IUnknown**)obj);
59 }
60
61 HRESULT __RPC_STUB IBindHost_MonikerBindToStorage_Stub(IBindHost* This,
62 IMoniker *moniker, IBindCtx *bc, IBindStatusCallback *bsc,
63 REFIID riid, IUnknown **obj)
64 {
65 TRACE("(%p %p %p %p %s %p)\n", This, moniker, bc, bsc, debugstr_guid(riid), obj);
66 return IBindHost_MonikerBindToStorage(This, moniker, bc, bsc, riid, (void**)obj);
67 }
68
69 HRESULT CALLBACK IBindHost_MonikerBindToObject_Proxy(IBindHost* This,
70 IMoniker *moniker, IBindCtx *bc, IBindStatusCallback *bsc,
71 REFIID riid, void **obj)
72 {
73 TRACE("(%p %p %p %p %s %p)\n", This, moniker, bc, bsc, debugstr_guid(riid), obj);
74 return IBindHost_RemoteMonikerBindToObject_Proxy(This, moniker, bc, bsc, riid, (IUnknown**)obj);
75 }
76
77 HRESULT __RPC_STUB IBindHost_MonikerBindToObject_Stub(IBindHost* This,
78 IMoniker *moniker, IBindCtx *bc, IBindStatusCallback *bsc,
79 REFIID riid, IUnknown **obj)
80 {
81 TRACE("(%p %p %p %p %s %p)\n", This, moniker, bc, bsc, debugstr_guid(riid), obj);
82 return IBindHost_MonikerBindToObject(This, moniker, bc, bsc, riid, (void**)obj);
83 }
84
85 static HRESULT marshal_stgmed(STGMEDIUM *stgmed, RemSTGMEDIUM **ret)
86 {
87 RemSTGMEDIUM *rem_stgmed;
88 IStream *stream = NULL;
89 ULONG size = 0;
90 HRESULT hres = S_OK;
91
92 if((stgmed->tymed == TYMED_ISTREAM && stgmed->u.pstm) || stgmed->pUnkForRelease) {
93 hres = CreateStreamOnHGlobal(NULL, TRUE, &stream);
94 if(FAILED(hres))
95 return hres;
96 }
97
98 switch(stgmed->tymed) {
99 case TYMED_NULL:
100 break;
101 case TYMED_ISTREAM:
102 if(stgmed->u.pstm)
103 hres = CoMarshalInterface(stream, &IID_IStream, (IUnknown*)stgmed->u.pstm,
104 MSHCTX_LOCAL, NULL, MSHLFLAGS_NORMAL);
105 break;
106 default:
107 FIXME("unsupported tymed %u\n", stgmed->tymed);
108 break;
109 }
110
111 if(SUCCEEDED(hres) && stgmed->pUnkForRelease)
112 hres = CoMarshalInterface(stream, &IID_IUnknown, stgmed->pUnkForRelease,
113 MSHCTX_LOCAL, NULL, MSHLFLAGS_NORMAL);
114 if(FAILED(hres)) {
115 if(stream)
116 IStream_Release(stream);
117 return hres;
118 }
119
120 if(stream) {
121 LARGE_INTEGER zero;
122 ULARGE_INTEGER off;
123
124 zero.QuadPart = 0;
125 IStream_Seek(stream, zero, STREAM_SEEK_CUR, &off);
126 size = off.QuadPart;
127 IStream_Seek(stream, zero, STREAM_SEEK_SET, &off);
128 }
129
130 rem_stgmed = heap_alloc_zero(FIELD_OFFSET(RemSTGMEDIUM, data[size]));
131 if(!rem_stgmed) {
132 if(stream)
133 IStream_Release(stream);
134 return E_OUTOFMEMORY;
135 }
136
137 rem_stgmed->tymed = stgmed->tymed;
138 rem_stgmed->dwHandleType = 0;
139 rem_stgmed->pData = stgmed->u.pstm != NULL;
140 rem_stgmed->pUnkForRelease = stgmed->pUnkForRelease != NULL;
141 rem_stgmed->cbData = size;
142 if(stream) {
143 IStream_Read(stream, rem_stgmed->data, size, &size);
144 IStream_Release(stream);
145 }
146
147 *ret = rem_stgmed;
148 return S_OK;
149 }
150
151 static HRESULT unmarshal_stgmed(RemSTGMEDIUM *rem_stgmed, STGMEDIUM *stgmed)
152 {
153 IStream *stream = NULL;
154 HRESULT hres = S_OK;
155
156 stgmed->tymed = rem_stgmed->tymed;
157
158 if((stgmed->tymed == TYMED_ISTREAM && rem_stgmed->pData) || rem_stgmed->pUnkForRelease) {
159 LARGE_INTEGER zero;
160
161 hres = CreateStreamOnHGlobal(NULL, TRUE, &stream);
162 if(FAILED(hres))
163 return hres;
164
165 hres = IStream_Write(stream, rem_stgmed->data, rem_stgmed->cbData, NULL);
166 if(FAILED(hres)) {
167 IStream_Release(stream);
168 return hres;
169 }
170
171 zero.QuadPart = 0;
172 IStream_Seek(stream, zero, STREAM_SEEK_SET, NULL);
173 }
174
175 switch(stgmed->tymed) {
176 case TYMED_NULL:
177 break;
178 case TYMED_ISTREAM:
179 if(rem_stgmed->pData)
180 hres = CoUnmarshalInterface(stream, &IID_IStream, (void**)&stgmed->u.pstm);
181 break;
182 default:
183 FIXME("unsupported tymed %u\n", stgmed->tymed);
184 break;
185 }
186
187 if(SUCCEEDED(hres) && rem_stgmed->pUnkForRelease)
188 hres = CoUnmarshalInterface(stream, &IID_IUnknown, (void**)&stgmed->pUnkForRelease);
189 if(stream)
190 IStream_Release(stream);
191 return hres;
192 }
193
194 static void proxy_marshal_bindinfo(BINDINFO *bindinfo, RemBINDINFO *rem_bindinfo)
195 {
196 rem_bindinfo->szExtraInfo = bindinfo->szExtraInfo;
197 rem_bindinfo->grfBindInfoF = bindinfo->grfBindInfoF;
198 rem_bindinfo->dwBindVerb = bindinfo->dwBindVerb;
199 rem_bindinfo->szCustomVerb = bindinfo->szCustomVerb;
200 rem_bindinfo->cbstgmedData = bindinfo->cbstgmedData;
201 }
202
203 static void proxy_unmarshal_bindinfo(RemBINDINFO *rem_bindinfo, BINDINFO *bindinfo)
204 {
205 bindinfo->szExtraInfo = rem_bindinfo->szExtraInfo;
206 bindinfo->grfBindInfoF = rem_bindinfo->grfBindInfoF;
207 bindinfo->dwBindVerb = rem_bindinfo->dwBindVerb;
208 bindinfo->szCustomVerb = rem_bindinfo->szCustomVerb;
209 bindinfo->cbstgmedData = rem_bindinfo->cbstgmedData;
210 bindinfo->dwOptions = rem_bindinfo->dwOptions;
211 bindinfo->dwOptionsFlags = rem_bindinfo->dwOptionsFlags;
212 bindinfo->dwCodePage = rem_bindinfo->dwCodePage;
213 bindinfo->iid = IID_NULL;
214 bindinfo->pUnk = NULL;
215 }
216
217 static void stub_unmarshal_bindinfo(RemBINDINFO *rem_bindinfo, BINDINFO *bindinfo)
218 {
219 bindinfo->szExtraInfo = rem_bindinfo->szExtraInfo;
220 bindinfo->grfBindInfoF = rem_bindinfo->grfBindInfoF;
221 bindinfo->dwBindVerb = rem_bindinfo->dwBindVerb;
222 bindinfo->szCustomVerb = rem_bindinfo->szCustomVerb;
223 bindinfo->cbstgmedData = rem_bindinfo->cbstgmedData;
224
225 if(bindinfo->stgmedData.tymed != TYMED_NULL)
226 WARN("stgmed data (tymed %u) will be lost!\n", bindinfo->stgmedData.tymed);
227 }
228
229 static void stub_marshal_bindinfo(BINDINFO *bindinfo, RemBINDINFO *rem_bindinfo)
230 {
231 rem_bindinfo->cbSize = sizeof(*rem_bindinfo);
232 rem_bindinfo->szExtraInfo = bindinfo->szExtraInfo;
233 rem_bindinfo->grfBindInfoF = bindinfo->grfBindInfoF;
234 rem_bindinfo->dwBindVerb = bindinfo->dwBindVerb;
235 rem_bindinfo->szCustomVerb = bindinfo->szCustomVerb;
236 rem_bindinfo->cbstgmedData = bindinfo->cbstgmedData;
237 rem_bindinfo->dwOptions = bindinfo->dwOptions;
238 rem_bindinfo->dwOptionsFlags = bindinfo->dwOptionsFlags;
239 rem_bindinfo->dwCodePage = bindinfo->dwCodePage;
240 rem_bindinfo->pUnk = NULL;
241 rem_bindinfo->dwReserved = bindinfo->dwReserved;
242 }
243
244
245 HRESULT CALLBACK IBindStatusCallbackEx_GetBindInfoEx_Proxy(
246 IBindStatusCallbackEx* This, DWORD *grfBINDF, BINDINFO *bindinfo,
247 DWORD *grfBINDF2, DWORD *pdwReserved)
248 {
249 RemBINDINFO rem_bindinfo = {sizeof(rem_bindinfo)};
250 RemSTGMEDIUM rem_stgmed = {0};
251 HRESULT hres;
252
253 TRACE("(%p)->(%p %p %p %p)\n", This, grfBINDF, bindinfo, grfBINDF2, pdwReserved);
254
255 proxy_marshal_bindinfo(bindinfo, &rem_bindinfo);
256 hres = IBindStatusCallbackEx_RemoteGetBindInfoEx_Proxy(This, grfBINDF, &rem_bindinfo,
257 &rem_stgmed, grfBINDF2, pdwReserved);
258 proxy_unmarshal_bindinfo(&rem_bindinfo, bindinfo);
259 return hres;
260 }
261
262 HRESULT __RPC_STUB IBindStatusCallbackEx_GetBindInfoEx_Stub(
263 IBindStatusCallbackEx* This, DWORD *grfBINDF, RemBINDINFO *rem_bindinfo,
264 RemSTGMEDIUM *rem_stgmed, DWORD *grfBINDF2, DWORD *pdwReserved)
265 {
266 BINDINFO bindinfo = {sizeof(bindinfo)};
267 HRESULT hres;
268
269 TRACE("(%p)->(%p %p %p %p %p)\n", This, grfBINDF, rem_bindinfo, rem_stgmed, grfBINDF2, pdwReserved);
270
271 /*
272 * Although arguments suggest support for STGMEDIUM from BINDINFO, tests show
273 * that it's not supported and returned data is lost.
274 */
275 stub_unmarshal_bindinfo(rem_bindinfo, &bindinfo);
276 hres = IBindStatusCallbackEx_GetBindInfoEx(This, grfBINDF, &bindinfo, grfBINDF2, pdwReserved);
277 stub_marshal_bindinfo(&bindinfo, rem_bindinfo);
278 return hres;
279 }
280 HRESULT CALLBACK IBindStatusCallback_GetBindInfo_Proxy(
281 IBindStatusCallback* This, DWORD *grfBINDF, BINDINFO *bindinfo)
282 {
283 RemBINDINFO rem_bindinfo = {sizeof(rem_bindinfo)};
284 RemSTGMEDIUM rem_stgmed = {0};
285 HRESULT hres;
286
287 TRACE("(%p)->(%p %p)\n", This, grfBINDF, bindinfo);
288
289 proxy_marshal_bindinfo(bindinfo, &rem_bindinfo);
290 hres = IBindStatusCallback_RemoteGetBindInfo_Proxy(This, grfBINDF, &rem_bindinfo, &rem_stgmed);
291 proxy_unmarshal_bindinfo(&rem_bindinfo, bindinfo);
292 return hres;
293 }
294
295 HRESULT __RPC_STUB IBindStatusCallback_GetBindInfo_Stub(
296 IBindStatusCallback* This, DWORD *grfBINDF,
297 RemBINDINFO *rem_bindinfo, RemSTGMEDIUM *rem_stgmed)
298 {
299 BINDINFO bindinfo = {sizeof(bindinfo)};
300 HRESULT hres;
301
302 TRACE("(%p)->(%p %p %p)\n", This, grfBINDF, rem_bindinfo, rem_stgmed);
303
304 stub_unmarshal_bindinfo(rem_bindinfo, &bindinfo);
305 hres = IBindStatusCallback_GetBindInfo(This, grfBINDF, &bindinfo);
306 stub_marshal_bindinfo(&bindinfo, rem_bindinfo);
307 return hres;
308 }
309
310 HRESULT CALLBACK IBindStatusCallback_OnDataAvailable_Proxy(
311 IBindStatusCallback* This, DWORD grfBSCF, DWORD dwSize,
312 FORMATETC *pformatetc, STGMEDIUM *pstgmed)
313 {
314 RemFORMATETC rem_formatetc;
315 RemSTGMEDIUM *rem_stgmed;
316 HRESULT hres;
317
318 TRACE("(%p)->(%x %u %p %p)\n", This, grfBSCF, dwSize, pformatetc, pstgmed);
319
320 hres = marshal_stgmed(pstgmed, &rem_stgmed);
321 if(FAILED(hres))
322 return hres;
323
324 rem_formatetc.cfFormat = pformatetc->cfFormat;
325 rem_formatetc.ptd = 0;
326 rem_formatetc.dwAspect = pformatetc->dwAspect;
327 rem_formatetc.lindex = pformatetc->lindex;
328 rem_formatetc.tymed = pformatetc->tymed;
329
330 hres = IBindStatusCallback_RemoteOnDataAvailable_Proxy(This, grfBSCF, dwSize, &rem_formatetc, rem_stgmed);
331
332 heap_free(rem_stgmed);
333 return hres;
334 }
335
336 HRESULT __RPC_STUB IBindStatusCallback_OnDataAvailable_Stub(
337 IBindStatusCallback* This, DWORD grfBSCF, DWORD dwSize,
338 RemFORMATETC *pformatetc, RemSTGMEDIUM *pstgmed)
339 {
340 STGMEDIUM stgmed = { TYMED_NULL };
341 FORMATETC formatetc;
342 HRESULT hres;
343
344 TRACE("(%p)->(%x %u %p %p)\n", This, grfBSCF, dwSize, pformatetc, pstgmed);
345
346 hres = unmarshal_stgmed(pstgmed, &stgmed);
347 if(FAILED(hres))
348 return hres;
349
350 formatetc.cfFormat = pformatetc->cfFormat;
351 formatetc.ptd = NULL;
352 formatetc.dwAspect = pformatetc->dwAspect;
353 formatetc.lindex = pformatetc->lindex;
354 formatetc.tymed = pformatetc->tymed;
355
356 hres = IBindStatusCallback_OnDataAvailable(This, grfBSCF, dwSize, &formatetc, &stgmed);
357
358 ReleaseStgMedium(&stgmed);
359 return hres;
360 }
361
362 HRESULT CALLBACK IBinding_GetBindResult_Proxy(IBinding* This,
363 CLSID *pclsidProtocol, DWORD *pdwResult,
364 LPOLESTR *pszResult, DWORD *pdwReserved)
365 {
366 FIXME("stub\n");
367 return E_NOTIMPL;
368 }
369
370 HRESULT __RPC_STUB IBinding_GetBindResult_Stub(IBinding* This,
371 CLSID *pclsidProtocol, DWORD *pdwResult,
372 LPOLESTR *pszResult, DWORD dwReserved)
373 {
374 FIXME("stub\n");
375 return E_NOTIMPL;
376 }