xref: /reactos/dll/win32/urlmon/usrmarshal.c (revision c7bba39a)
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 #define NONAMELESSUNION
20 
21 #include "urlmon_main.h"
22 
23 #include "wine/debug.h"
24 
25 WINE_DEFAULT_DEBUG_CHANNEL(urlmon);
26 
27 HRESULT CALLBACK IWinInetHttpInfo_QueryInfo_Proxy(IWinInetHttpInfo* This,
28     DWORD dwOption, LPVOID pBuffer, DWORD *pcbBuf, DWORD *pdwFlags,
29     DWORD *pdwReserved)
30 {
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);
33 }
34 
35 HRESULT __RPC_STUB IWinInetHttpInfo_QueryInfo_Stub(IWinInetHttpInfo* This,
36     DWORD dwOption, BYTE *pBuffer, DWORD *pcbBuf, DWORD *pdwFlags,
37     DWORD *pdwReserved)
38 {
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);
41 }
42 
43 HRESULT CALLBACK IWinInetInfo_QueryOption_Proxy(IWinInetInfo* This,
44         DWORD dwOption, LPVOID pBuffer, DWORD *pcbBuf)
45 {
46     TRACE("(%p %x %p %p)\n", This, dwOption, pBuffer, pcbBuf);
47     return IWinInetInfo_RemoteQueryOption_Proxy(This, dwOption, pBuffer, pcbBuf);
48 }
49 
50 HRESULT __RPC_STUB IWinInetInfo_QueryOption_Stub(IWinInetInfo* This,
51         DWORD dwOption, BYTE *pBuffer, DWORD *pcbBuf)
52 {
53     TRACE("(%p %x %p %p)\n", This, dwOption, pBuffer, pcbBuf);
54     return IWinInetInfo_QueryOption(This, dwOption, pBuffer, pcbBuf);
55 }
56 
57 HRESULT CALLBACK IBindHost_MonikerBindToStorage_Proxy(IBindHost* This,
58         IMoniker *moniker, IBindCtx *bc, IBindStatusCallback *bsc,
59         REFIID riid, void **obj)
60 {
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);
63 }
64 
65 HRESULT __RPC_STUB IBindHost_MonikerBindToStorage_Stub(IBindHost* This,
66         IMoniker *moniker, IBindCtx *bc, IBindStatusCallback *bsc,
67         REFIID riid, IUnknown **obj)
68 {
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);
71 }
72 
73 HRESULT CALLBACK IBindHost_MonikerBindToObject_Proxy(IBindHost* This,
74         IMoniker *moniker, IBindCtx *bc, IBindStatusCallback *bsc,
75         REFIID riid, void **obj)
76 {
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);
79 }
80 
81 HRESULT __RPC_STUB IBindHost_MonikerBindToObject_Stub(IBindHost* This,
82         IMoniker *moniker, IBindCtx *bc, IBindStatusCallback *bsc,
83         REFIID riid, IUnknown **obj)
84 {
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);
87 }
88 
89 static HRESULT marshal_stgmed(STGMEDIUM *stgmed, RemSTGMEDIUM **ret)
90 {
91     RemSTGMEDIUM *rem_stgmed;
92     IStream *stream = NULL;
93     ULONG size = 0;
94     HRESULT hres = S_OK;
95 
96     if((stgmed->tymed == TYMED_ISTREAM && stgmed->u.pstm) || stgmed->pUnkForRelease) {
97         hres = CreateStreamOnHGlobal(NULL, TRUE, &stream);
98         if(FAILED(hres))
99             return hres;
100     }
101 
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;
113     }
114 
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;
122     }
123 
124     if(stream) {
125         LARGE_INTEGER zero;
126         ULARGE_INTEGER off;
127 
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);
132     }
133 
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;
139     }
140 
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);
149     }
150 
151     *ret = rem_stgmed;
152     return S_OK;
153 }
154 
155 static HRESULT unmarshal_stgmed(RemSTGMEDIUM *rem_stgmed, STGMEDIUM *stgmed)
156 {
157     IStream *stream = NULL;
158     HRESULT hres = S_OK;
159 
160     stgmed->tymed = rem_stgmed->tymed;
161 
162     if((stgmed->tymed == TYMED_ISTREAM && rem_stgmed->pData) || rem_stgmed->pUnkForRelease) {
163         LARGE_INTEGER zero;
164 
165         hres = CreateStreamOnHGlobal(NULL, TRUE, &stream);
166         if(FAILED(hres))
167             return hres;
168 
169         hres = IStream_Write(stream, rem_stgmed->data, rem_stgmed->cbData, NULL);
170         if(FAILED(hres)) {
171             IStream_Release(stream);
172             return hres;
173         }
174 
175         zero.QuadPart = 0;
176         IStream_Seek(stream, zero, STREAM_SEEK_SET, NULL);
177     }
178 
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;
189     }
190 
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;
196 }
197 
198 static void proxy_marshal_bindinfo(BINDINFO *bindinfo, RemBINDINFO *rem_bindinfo)
199 {
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;
205 }
206 
207 static void proxy_unmarshal_bindinfo(RemBINDINFO *rem_bindinfo, BINDINFO *bindinfo)
208 {
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;
219 }
220 
221 static void stub_unmarshal_bindinfo(RemBINDINFO *rem_bindinfo, BINDINFO *bindinfo)
222 {
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;
228 
229     if(bindinfo->stgmedData.tymed != TYMED_NULL)
230         WARN("stgmed data (tymed %u) will be lost!\n", bindinfo->stgmedData.tymed);
231 }
232 
233 static void stub_marshal_bindinfo(BINDINFO *bindinfo, RemBINDINFO *rem_bindinfo)
234 {
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;
246 }
247 
248 
249 HRESULT CALLBACK IBindStatusCallbackEx_GetBindInfoEx_Proxy(
250         IBindStatusCallbackEx* This, DWORD *grfBINDF, BINDINFO *bindinfo,
251         DWORD *grfBINDF2, DWORD *pdwReserved)
252 {
253     RemBINDINFO rem_bindinfo = {sizeof(rem_bindinfo)};
254     RemSTGMEDIUM rem_stgmed = {0};
255     HRESULT hres;
256 
257     TRACE("(%p)->(%p %p %p %p)\n", This, grfBINDF, bindinfo, grfBINDF2, pdwReserved);
258 
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;
264 }
265 
266 HRESULT __RPC_STUB IBindStatusCallbackEx_GetBindInfoEx_Stub(
267         IBindStatusCallbackEx* This, DWORD *grfBINDF, RemBINDINFO *rem_bindinfo,
268         RemSTGMEDIUM *rem_stgmed, DWORD *grfBINDF2, DWORD *pdwReserved)
269 {
270     BINDINFO bindinfo = {sizeof(bindinfo)};
271     HRESULT hres;
272 
273     TRACE("(%p)->(%p %p %p %p %p)\n", This, grfBINDF, rem_bindinfo, rem_stgmed, grfBINDF2, pdwReserved);
274 
275     /*
276      * Although arguments suggest support for STGMEDIUM from BINDINFO, tests show
277      * that it's not supported and returned data is lost.
278      */
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;
283 }
284 HRESULT CALLBACK IBindStatusCallback_GetBindInfo_Proxy(
285         IBindStatusCallback* This, DWORD *grfBINDF, BINDINFO *bindinfo)
286 {
287     RemBINDINFO rem_bindinfo = {sizeof(rem_bindinfo)};
288     RemSTGMEDIUM rem_stgmed = {0};
289     HRESULT hres;
290 
291     TRACE("(%p)->(%p %p)\n", This, grfBINDF, bindinfo);
292 
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;
297 }
298 
299 HRESULT __RPC_STUB IBindStatusCallback_GetBindInfo_Stub(
300         IBindStatusCallback* This, DWORD *grfBINDF,
301         RemBINDINFO *rem_bindinfo, RemSTGMEDIUM *rem_stgmed)
302 {
303     BINDINFO bindinfo = {sizeof(bindinfo)};
304     HRESULT hres;
305 
306     TRACE("(%p)->(%p %p %p)\n", This, grfBINDF, rem_bindinfo, rem_stgmed);
307 
308     stub_unmarshal_bindinfo(rem_bindinfo, &bindinfo);
309     hres = IBindStatusCallback_GetBindInfo(This, grfBINDF, &bindinfo);
310     stub_marshal_bindinfo(&bindinfo, rem_bindinfo);
311     return hres;
312 }
313 
314 HRESULT CALLBACK IBindStatusCallback_OnDataAvailable_Proxy(
315         IBindStatusCallback* This, DWORD grfBSCF, DWORD dwSize,
316         FORMATETC *pformatetc, STGMEDIUM *pstgmed)
317 {
318     RemFORMATETC rem_formatetc;
319     RemSTGMEDIUM *rem_stgmed;
320     HRESULT hres;
321 
322     TRACE("(%p)->(%x %u %p %p)\n", This, grfBSCF, dwSize, pformatetc, pstgmed);
323 
324     hres = marshal_stgmed(pstgmed, &rem_stgmed);
325     if(FAILED(hres))
326         return hres;
327 
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;
333 
334     hres = IBindStatusCallback_RemoteOnDataAvailable_Proxy(This, grfBSCF, dwSize, &rem_formatetc, rem_stgmed);
335 
336     heap_free(rem_stgmed);
337     return hres;
338 }
339 
340 HRESULT __RPC_STUB IBindStatusCallback_OnDataAvailable_Stub(
341         IBindStatusCallback* This, DWORD grfBSCF, DWORD dwSize,
342         RemFORMATETC *pformatetc, RemSTGMEDIUM *pstgmed)
343 {
344     STGMEDIUM stgmed = { TYMED_NULL };
345     FORMATETC formatetc;
346     HRESULT hres;
347 
348     TRACE("(%p)->(%x %u %p %p)\n", This, grfBSCF, dwSize, pformatetc, pstgmed);
349 
350     hres = unmarshal_stgmed(pstgmed, &stgmed);
351     if(FAILED(hres))
352         return hres;
353 
354     formatetc.cfFormat = pformatetc->cfFormat;
355     formatetc.ptd = NULL;
356     formatetc.dwAspect = pformatetc->dwAspect;
357     formatetc.lindex = pformatetc->lindex;
358     formatetc.tymed = pformatetc->tymed;
359 
360     hres = IBindStatusCallback_OnDataAvailable(This, grfBSCF, dwSize, &formatetc, &stgmed);
361 
362     ReleaseStgMedium(&stgmed);
363     return hres;
364 }
365 
366 HRESULT CALLBACK IBinding_GetBindResult_Proxy(IBinding* This,
367         CLSID *pclsidProtocol, DWORD *pdwResult,
368         LPOLESTR *pszResult, DWORD *pdwReserved)
369 {
370     FIXME("stub\n");
371     return E_NOTIMPL;
372 }
373 
374 HRESULT __RPC_STUB IBinding_GetBindResult_Stub(IBinding* This,
375         CLSID *pclsidProtocol, DWORD *pdwResult,
376         LPOLESTR *pszResult, DWORD dwReserved)
377 {
378     FIXME("stub\n");
379     return E_NOTIMPL;
380 }
381