Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenumstream.c
Go to the documentation of this file.
00001 /* 00002 * Based on ../shell32/memorystream.c 00003 * 00004 * Copyright 1999 Juergen Schmied 00005 * Copyright 2003 Mike McCormack for CodeWeavers 00006 * 00007 * This library is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public 00009 * License as published by the Free Software Foundation; either 00010 * version 2.1 of the License, or (at your option) any later version. 00011 * 00012 * This library is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 * Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with this library; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00020 */ 00021 00022 #include "urlmon_main.h" 00023 00024 #include "winreg.h" 00025 #include "winternl.h" 00026 #include "wininet.h" 00027 #include "shlwapi.h" 00028 00029 #include "wine/debug.h" 00030 00031 WINE_DEFAULT_DEBUG_CHANNEL(urlmon); 00032 00033 typedef struct ProxyBindStatusCallback 00034 { 00035 IBindStatusCallback IBindStatusCallback_iface; 00036 00037 IBindStatusCallback *pBSC; 00038 } ProxyBindStatusCallback; 00039 00040 static inline ProxyBindStatusCallback *impl_from_IBindStatusCallback(IBindStatusCallback *iface) 00041 { 00042 return CONTAINING_RECORD(iface, ProxyBindStatusCallback, IBindStatusCallback_iface); 00043 } 00044 00045 static HRESULT WINAPI ProxyBindStatusCallback_QueryInterface(IBindStatusCallback *iface, REFIID riid, void **ppv) 00046 { 00047 if (IsEqualGUID(&IID_IBindStatusCallback, riid) || 00048 IsEqualGUID(&IID_IUnknown, riid)) 00049 { 00050 *ppv = iface; 00051 IUnknown_AddRef(iface); 00052 return S_OK; 00053 } 00054 00055 *ppv = NULL; 00056 return E_NOINTERFACE; 00057 } 00058 00059 static ULONG WINAPI ProxyBindStatusCallback_AddRef(IBindStatusCallback *iface) 00060 { 00061 return 2; 00062 } 00063 00064 static ULONG WINAPI ProxyBindStatusCallback_Release(IBindStatusCallback *iface) 00065 { 00066 return 1; 00067 } 00068 00069 static HRESULT WINAPI ProxyBindStatusCallback_OnStartBinding(IBindStatusCallback *iface, DWORD dwReserved, 00070 IBinding *pib) 00071 { 00072 ProxyBindStatusCallback *This = impl_from_IBindStatusCallback(iface); 00073 00074 if(This->pBSC) 00075 return IBindStatusCallback_OnStartBinding(This->pBSC, dwReserved, pib); 00076 00077 return S_OK; 00078 } 00079 00080 static HRESULT WINAPI ProxyBindStatusCallback_GetPriority(IBindStatusCallback *iface, LONG *pnPriority) 00081 { 00082 ProxyBindStatusCallback *This = impl_from_IBindStatusCallback(iface); 00083 00084 if(This->pBSC) 00085 return IBindStatusCallback_GetPriority(This->pBSC, pnPriority); 00086 00087 return S_OK; 00088 } 00089 00090 static HRESULT WINAPI ProxyBindStatusCallback_OnLowResource(IBindStatusCallback *iface, DWORD reserved) 00091 { 00092 ProxyBindStatusCallback *This = impl_from_IBindStatusCallback(iface); 00093 00094 if(This->pBSC) 00095 return IBindStatusCallback_OnLowResource(This->pBSC, reserved); 00096 00097 return S_OK; 00098 } 00099 00100 static HRESULT WINAPI ProxyBindStatusCallback_OnProgress(IBindStatusCallback *iface, ULONG ulProgress, 00101 ULONG ulProgressMax, ULONG ulStatusCode, LPCWSTR szStatusText) 00102 { 00103 ProxyBindStatusCallback *This = impl_from_IBindStatusCallback(iface); 00104 00105 if(This->pBSC) 00106 return IBindStatusCallback_OnProgress(This->pBSC, ulProgress, 00107 ulProgressMax, ulStatusCode, 00108 szStatusText); 00109 00110 return S_OK; 00111 } 00112 00113 static HRESULT WINAPI ProxyBindStatusCallback_OnStopBinding(IBindStatusCallback *iface, HRESULT hresult, LPCWSTR szError) 00114 { 00115 ProxyBindStatusCallback *This = impl_from_IBindStatusCallback(iface); 00116 00117 if(This->pBSC) 00118 return IBindStatusCallback_OnStopBinding(This->pBSC, hresult, szError); 00119 00120 return S_OK; 00121 } 00122 00123 static HRESULT WINAPI ProxyBindStatusCallback_GetBindInfo(IBindStatusCallback *iface, DWORD *grfBINDF, BINDINFO *pbindinfo) 00124 { 00125 ProxyBindStatusCallback *This = impl_from_IBindStatusCallback(iface); 00126 00127 if(This->pBSC) 00128 return IBindStatusCallback_GetBindInfo(This->pBSC, grfBINDF, pbindinfo); 00129 00130 return E_INVALIDARG; 00131 } 00132 00133 static HRESULT WINAPI ProxyBindStatusCallback_OnDataAvailable(IBindStatusCallback *iface, DWORD grfBSCF, 00134 DWORD dwSize, FORMATETC* pformatetc, STGMEDIUM* pstgmed) 00135 { 00136 ProxyBindStatusCallback *This = impl_from_IBindStatusCallback(iface); 00137 00138 if(This->pBSC) 00139 return IBindStatusCallback_OnDataAvailable(This->pBSC, grfBSCF, dwSize, 00140 pformatetc, pstgmed); 00141 00142 return S_OK; 00143 } 00144 00145 static HRESULT WINAPI ProxyBindStatusCallback_OnObjectAvailable(IBindStatusCallback *iface, REFIID riid, IUnknown *punk) 00146 { 00147 ProxyBindStatusCallback *This = impl_from_IBindStatusCallback(iface); 00148 00149 if(This->pBSC) 00150 return IBindStatusCallback_OnObjectAvailable(This->pBSC, riid, punk); 00151 00152 return S_OK; 00153 } 00154 00155 static HRESULT WINAPI BlockingBindStatusCallback_OnDataAvailable(IBindStatusCallback *iface, DWORD grfBSCF, 00156 DWORD dwSize, FORMATETC* pformatetc, STGMEDIUM* pstgmed) 00157 { 00158 return S_OK; 00159 } 00160 00161 static const IBindStatusCallbackVtbl BlockingBindStatusCallbackVtbl = 00162 { 00163 ProxyBindStatusCallback_QueryInterface, 00164 ProxyBindStatusCallback_AddRef, 00165 ProxyBindStatusCallback_Release, 00166 ProxyBindStatusCallback_OnStartBinding, 00167 ProxyBindStatusCallback_GetPriority, 00168 ProxyBindStatusCallback_OnLowResource, 00169 ProxyBindStatusCallback_OnProgress, 00170 ProxyBindStatusCallback_OnStopBinding, 00171 ProxyBindStatusCallback_GetBindInfo, 00172 BlockingBindStatusCallback_OnDataAvailable, 00173 ProxyBindStatusCallback_OnObjectAvailable 00174 }; 00175 00176 static HRESULT WINAPI AsyncBindStatusCallback_GetBindInfo(IBindStatusCallback *iface, DWORD *grfBINDF, BINDINFO *pbindinfo) 00177 { 00178 ProxyBindStatusCallback *This = impl_from_IBindStatusCallback(iface); 00179 HRESULT hr = IBindStatusCallback_GetBindInfo(This->pBSC, grfBINDF, pbindinfo); 00180 *grfBINDF |= BINDF_PULLDATA | BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE; 00181 return hr; 00182 } 00183 00184 static const IBindStatusCallbackVtbl AsyncBindStatusCallbackVtbl = 00185 { 00186 ProxyBindStatusCallback_QueryInterface, 00187 ProxyBindStatusCallback_AddRef, 00188 ProxyBindStatusCallback_Release, 00189 ProxyBindStatusCallback_OnStartBinding, 00190 ProxyBindStatusCallback_GetPriority, 00191 ProxyBindStatusCallback_OnLowResource, 00192 ProxyBindStatusCallback_OnProgress, 00193 ProxyBindStatusCallback_OnStopBinding, 00194 AsyncBindStatusCallback_GetBindInfo, 00195 ProxyBindStatusCallback_OnDataAvailable, 00196 ProxyBindStatusCallback_OnObjectAvailable 00197 }; 00198 00199 static HRESULT URLStartDownload(LPCWSTR szURL, LPSTREAM *ppStream, IBindStatusCallback *pBSC) 00200 { 00201 HRESULT hr; 00202 IMoniker *pMoniker; 00203 IBindCtx *pbc; 00204 00205 *ppStream = NULL; 00206 00207 hr = CreateURLMoniker(NULL, szURL, &pMoniker); 00208 if (FAILED(hr)) 00209 return hr; 00210 00211 hr = CreateBindCtx(0, &pbc); 00212 if (FAILED(hr)) 00213 { 00214 IMoniker_Release(pMoniker); 00215 return hr; 00216 } 00217 00218 hr = RegisterBindStatusCallback(pbc, pBSC, NULL, 0); 00219 if (FAILED(hr)) 00220 { 00221 IBindCtx_Release(pbc); 00222 IMoniker_Release(pMoniker); 00223 return hr; 00224 } 00225 00226 hr = IMoniker_BindToStorage(pMoniker, pbc, NULL, &IID_IStream, (void **)ppStream); 00227 00228 /* BindToStorage returning E_PENDING because it's asynchronous is not an error */ 00229 if (hr == E_PENDING) hr = S_OK; 00230 00231 IBindCtx_Release(pbc); 00232 IMoniker_Release(pMoniker); 00233 00234 return hr; 00235 } 00236 00237 /*********************************************************************** 00238 * URLOpenBlockingStreamA (URLMON.@) 00239 */ 00240 HRESULT WINAPI URLOpenBlockingStreamA(LPUNKNOWN pCaller, LPCSTR szURL, 00241 LPSTREAM *ppStream, DWORD dwReserved, 00242 LPBINDSTATUSCALLBACK lpfnCB) 00243 { 00244 LPWSTR szURLW; 00245 int len; 00246 HRESULT hr; 00247 00248 TRACE("(%p, %s, %p, 0x%x, %p)\n", pCaller, szURL, ppStream, dwReserved, lpfnCB); 00249 00250 if (!szURL || !ppStream) 00251 return E_INVALIDARG; 00252 00253 len = MultiByteToWideChar(CP_ACP, 0, szURL, -1, NULL, 0); 00254 szURLW = heap_alloc(len * sizeof(WCHAR)); 00255 if (!szURLW) 00256 { 00257 *ppStream = NULL; 00258 return E_OUTOFMEMORY; 00259 } 00260 MultiByteToWideChar(CP_ACP, 0, szURL, -1, szURLW, len); 00261 00262 hr = URLOpenBlockingStreamW(pCaller, szURLW, ppStream, dwReserved, lpfnCB); 00263 00264 heap_free(szURLW); 00265 00266 return hr; 00267 } 00268 00269 /*********************************************************************** 00270 * URLOpenBlockingStreamW (URLMON.@) 00271 */ 00272 HRESULT WINAPI URLOpenBlockingStreamW(LPUNKNOWN pCaller, LPCWSTR szURL, 00273 LPSTREAM *ppStream, DWORD dwReserved, 00274 LPBINDSTATUSCALLBACK lpfnCB) 00275 { 00276 ProxyBindStatusCallback blocking_bsc; 00277 00278 TRACE("(%p, %s, %p, 0x%x, %p)\n", pCaller, debugstr_w(szURL), ppStream, 00279 dwReserved, lpfnCB); 00280 00281 if (!szURL || !ppStream) 00282 return E_INVALIDARG; 00283 00284 blocking_bsc.IBindStatusCallback_iface.lpVtbl = &BlockingBindStatusCallbackVtbl; 00285 blocking_bsc.pBSC = lpfnCB; 00286 00287 return URLStartDownload(szURL, ppStream, &blocking_bsc.IBindStatusCallback_iface); 00288 } 00289 00290 /*********************************************************************** 00291 * URLOpenStreamA (URLMON.@) 00292 */ 00293 HRESULT WINAPI URLOpenStreamA(LPUNKNOWN pCaller, LPCSTR szURL, DWORD dwReserved, 00294 LPBINDSTATUSCALLBACK lpfnCB) 00295 { 00296 LPWSTR szURLW; 00297 int len; 00298 HRESULT hr; 00299 00300 TRACE("(%p, %s, 0x%x, %p)\n", pCaller, szURL, dwReserved, lpfnCB); 00301 00302 if (!szURL) 00303 return E_INVALIDARG; 00304 00305 len = MultiByteToWideChar(CP_ACP, 0, szURL, -1, NULL, 0); 00306 szURLW = heap_alloc(len * sizeof(WCHAR)); 00307 if (!szURLW) 00308 return E_OUTOFMEMORY; 00309 MultiByteToWideChar(CP_ACP, 0, szURL, -1, szURLW, len); 00310 00311 hr = URLOpenStreamW(pCaller, szURLW, dwReserved, lpfnCB); 00312 00313 heap_free(szURLW); 00314 00315 return hr; 00316 } 00317 00318 /*********************************************************************** 00319 * URLOpenStreamW (URLMON.@) 00320 */ 00321 HRESULT WINAPI URLOpenStreamW(LPUNKNOWN pCaller, LPCWSTR szURL, DWORD dwReserved, 00322 LPBINDSTATUSCALLBACK lpfnCB) 00323 { 00324 HRESULT hr; 00325 ProxyBindStatusCallback async_bsc; 00326 IStream *pStream; 00327 00328 TRACE("(%p, %s, 0x%x, %p)\n", pCaller, debugstr_w(szURL), dwReserved, 00329 lpfnCB); 00330 00331 if (!szURL) 00332 return E_INVALIDARG; 00333 00334 async_bsc.IBindStatusCallback_iface.lpVtbl = &AsyncBindStatusCallbackVtbl; 00335 async_bsc.pBSC = lpfnCB; 00336 00337 hr = URLStartDownload(szURL, &pStream, &async_bsc.IBindStatusCallback_iface); 00338 if (SUCCEEDED(hr) && pStream) 00339 IStream_Release(pStream); 00340 00341 return hr; 00342 } Generated on Wed May 23 2012 04:24:35 for ReactOS by
1.7.6.1
|