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