Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygendownload.c
Go to the documentation of this file.
00001 /* 00002 * Copyright 2008 Jacek Caban for CodeWeavers 00003 * 00004 * This library is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU Lesser General Public 00006 * License as published by the Free Software Foundation; either 00007 * version 2.1 of the License, or (at your option) any later version. 00008 * 00009 * This library is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 * Lesser General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU Lesser General Public 00015 * License along with this library; if not, write to the Free Software 00016 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00017 */ 00018 00019 #include "urlmon_main.h" 00020 #include "wine/debug.h" 00021 00022 WINE_DEFAULT_DEBUG_CHANNEL(urlmon); 00023 00024 typedef struct { 00025 IBindStatusCallback IBindStatusCallback_iface; 00026 IServiceProvider IServiceProvider_iface; 00027 00028 LONG ref; 00029 00030 IBindStatusCallback *callback; 00031 IBinding *binding; 00032 LPWSTR file_name; 00033 LPWSTR cache_file; 00034 } DownloadBSC; 00035 00036 static inline DownloadBSC *impl_from_IBindStatusCallback(IBindStatusCallback *iface) 00037 { 00038 return CONTAINING_RECORD(iface, DownloadBSC, IBindStatusCallback_iface); 00039 } 00040 00041 static inline DownloadBSC *impl_from_IServiceProvider(IServiceProvider *iface) 00042 { 00043 return CONTAINING_RECORD(iface, DownloadBSC, IServiceProvider_iface); 00044 } 00045 00046 static HRESULT WINAPI DownloadBSC_QueryInterface(IBindStatusCallback *iface, 00047 REFIID riid, void **ppv) 00048 { 00049 DownloadBSC *This = impl_from_IBindStatusCallback(iface); 00050 00051 *ppv = NULL; 00052 00053 if(IsEqualGUID(&IID_IUnknown, riid)) { 00054 TRACE("(%p)->(IID_IUnknown, %p)\n", This, ppv); 00055 *ppv = &This->IBindStatusCallback_iface; 00056 }else if(IsEqualGUID(&IID_IBindStatusCallback, riid)) { 00057 TRACE("(%p)->(IID_IBindStatusCallback, %p)\n", This, ppv); 00058 *ppv = &This->IBindStatusCallback_iface; 00059 }else if(IsEqualGUID(&IID_IServiceProvider, riid)) { 00060 TRACE("(%p)->(IID_IServiceProvider, %p)\n", This, ppv); 00061 *ppv = &This->IServiceProvider_iface; 00062 } 00063 00064 if(*ppv) { 00065 IBindStatusCallback_AddRef((IUnknown*)*ppv); 00066 return S_OK; 00067 } 00068 00069 TRACE("Unsupported riid = %s\n", debugstr_guid(riid)); 00070 return E_NOINTERFACE; 00071 } 00072 00073 static ULONG WINAPI DownloadBSC_AddRef(IBindStatusCallback *iface) 00074 { 00075 DownloadBSC *This = impl_from_IBindStatusCallback(iface); 00076 LONG ref = InterlockedIncrement(&This->ref); 00077 00078 TRACE("(%p) ref = %d\n", This, ref); 00079 00080 return ref; 00081 } 00082 00083 static ULONG WINAPI DownloadBSC_Release(IBindStatusCallback *iface) 00084 { 00085 DownloadBSC *This = impl_from_IBindStatusCallback(iface); 00086 LONG ref = InterlockedDecrement(&This->ref); 00087 00088 TRACE("(%p) ref = %d\n", This, ref); 00089 00090 if(!ref) { 00091 if(This->callback) 00092 IBindStatusCallback_Release(This->callback); 00093 if(This->binding) 00094 IBinding_Release(This->binding); 00095 heap_free(This->file_name); 00096 heap_free(This->cache_file); 00097 heap_free(This); 00098 } 00099 00100 return ref; 00101 } 00102 00103 static HRESULT WINAPI DownloadBSC_OnStartBinding(IBindStatusCallback *iface, 00104 DWORD dwReserved, IBinding *pbind) 00105 { 00106 DownloadBSC *This = impl_from_IBindStatusCallback(iface); 00107 HRESULT hres = S_OK; 00108 00109 TRACE("(%p)->(%d %p)\n", This, dwReserved, pbind); 00110 00111 if(This->callback) { 00112 hres = IBindStatusCallback_OnStartBinding(This->callback, dwReserved, pbind); 00113 00114 IBinding_AddRef(pbind); 00115 This->binding = pbind; 00116 } 00117 00118 /* Windows seems to ignore E_NOTIMPL if it's returned from the client. */ 00119 return hres == E_NOTIMPL ? S_OK : hres; 00120 } 00121 00122 static HRESULT WINAPI DownloadBSC_GetPriority(IBindStatusCallback *iface, LONG *pnPriority) 00123 { 00124 DownloadBSC *This = impl_from_IBindStatusCallback(iface); 00125 FIXME("(%p)->(%p)\n", This, pnPriority); 00126 return E_NOTIMPL; 00127 } 00128 00129 static HRESULT WINAPI DownloadBSC_OnLowResource(IBindStatusCallback *iface, DWORD reserved) 00130 { 00131 DownloadBSC *This = impl_from_IBindStatusCallback(iface); 00132 FIXME("(%p)->(%d)\n", This, reserved); 00133 return E_NOTIMPL; 00134 } 00135 00136 static HRESULT on_progress(DownloadBSC *This, ULONG progress, ULONG progress_max, ULONG status_code, LPCWSTR status_text) 00137 { 00138 HRESULT hres; 00139 00140 if(!This->callback) 00141 return S_OK; 00142 00143 hres = IBindStatusCallback_OnProgress(This->callback, progress, progress_max, status_code, status_text); 00144 if(hres == E_ABORT) { 00145 if(This->binding) 00146 IBinding_Abort(This->binding); 00147 else 00148 FIXME("No binding, not sure what to do!\n"); 00149 } 00150 00151 return hres; 00152 } 00153 00154 static HRESULT WINAPI DownloadBSC_OnProgress(IBindStatusCallback *iface, ULONG ulProgress, 00155 ULONG ulProgressMax, ULONG ulStatusCode, LPCWSTR szStatusText) 00156 { 00157 DownloadBSC *This = impl_from_IBindStatusCallback(iface); 00158 HRESULT hres = S_OK; 00159 00160 TRACE("%p)->(%u %u %u %s)\n", This, ulProgress, ulProgressMax, ulStatusCode, 00161 debugstr_w(szStatusText)); 00162 00163 switch(ulStatusCode) { 00164 case BINDSTATUS_CONNECTING: 00165 case BINDSTATUS_BEGINDOWNLOADDATA: 00166 case BINDSTATUS_DOWNLOADINGDATA: 00167 case BINDSTATUS_ENDDOWNLOADDATA: 00168 case BINDSTATUS_SENDINGREQUEST: 00169 case BINDSTATUS_MIMETYPEAVAILABLE: 00170 hres = on_progress(This, ulProgress, ulProgressMax, ulStatusCode, szStatusText); 00171 break; 00172 00173 case BINDSTATUS_CACHEFILENAMEAVAILABLE: 00174 hres = on_progress(This, ulProgress, ulProgressMax, ulStatusCode, szStatusText); 00175 This->cache_file = heap_strdupW(szStatusText); 00176 break; 00177 00178 case BINDSTATUS_FINDINGRESOURCE: /* FIXME */ 00179 break; 00180 00181 default: 00182 FIXME("Unsupported status %u\n", ulStatusCode); 00183 } 00184 00185 return hres; 00186 } 00187 00188 static HRESULT WINAPI DownloadBSC_OnStopBinding(IBindStatusCallback *iface, 00189 HRESULT hresult, LPCWSTR szError) 00190 { 00191 DownloadBSC *This = impl_from_IBindStatusCallback(iface); 00192 00193 TRACE("(%p)->(%08x %s)\n", This, hresult, debugstr_w(szError)); 00194 00195 if(This->file_name) { 00196 if(This->cache_file) { 00197 BOOL b; 00198 00199 b = CopyFileW(This->cache_file, This->file_name, FALSE); 00200 if(!b) 00201 FIXME("CopyFile failed: %u\n", GetLastError()); 00202 }else { 00203 FIXME("No cache file\n"); 00204 } 00205 } 00206 00207 if(This->callback) 00208 IBindStatusCallback_OnStopBinding(This->callback, hresult, szError); 00209 00210 if(This->binding) { 00211 IBinding_Release(This->binding); 00212 This->binding = NULL; 00213 } 00214 00215 return S_OK; 00216 } 00217 00218 static HRESULT WINAPI DownloadBSC_GetBindInfo(IBindStatusCallback *iface, 00219 DWORD *grfBINDF, BINDINFO *pbindinfo) 00220 { 00221 DownloadBSC *This = impl_from_IBindStatusCallback(iface); 00222 DWORD bindf = 0; 00223 00224 TRACE("(%p)->(%p %p)\n", This, grfBINDF, pbindinfo); 00225 00226 if(This->callback) { 00227 BINDINFO bindinfo; 00228 HRESULT hres; 00229 00230 memset(&bindinfo, 0, sizeof(bindinfo)); 00231 bindinfo.cbSize = sizeof(bindinfo); 00232 00233 hres = IBindStatusCallback_GetBindInfo(This->callback, &bindf, &bindinfo); 00234 if(SUCCEEDED(hres)) 00235 ReleaseBindInfo(&bindinfo); 00236 } 00237 00238 *grfBINDF = BINDF_PULLDATA | BINDF_NEEDFILE | (bindf & BINDF_ENFORCERESTRICTED); 00239 return S_OK; 00240 } 00241 00242 static HRESULT WINAPI DownloadBSC_OnDataAvailable(IBindStatusCallback *iface, 00243 DWORD grfBSCF, DWORD dwSize, FORMATETC *pformatetc, STGMEDIUM *pstgmed) 00244 { 00245 DownloadBSC *This = impl_from_IBindStatusCallback(iface); 00246 00247 TRACE("(%p)->(%08x %d %p %p)\n", This, grfBSCF, dwSize, pformatetc, pstgmed); 00248 00249 return S_OK; 00250 } 00251 00252 static HRESULT WINAPI DownloadBSC_OnObjectAvailable(IBindStatusCallback *iface, 00253 REFIID riid, IUnknown *punk) 00254 { 00255 DownloadBSC *This = impl_from_IBindStatusCallback(iface); 00256 FIXME("(%p)->(%s %p)\n", This, debugstr_guid(riid), punk); 00257 return E_NOTIMPL; 00258 } 00259 00260 static const IBindStatusCallbackVtbl BindStatusCallbackVtbl = { 00261 DownloadBSC_QueryInterface, 00262 DownloadBSC_AddRef, 00263 DownloadBSC_Release, 00264 DownloadBSC_OnStartBinding, 00265 DownloadBSC_GetPriority, 00266 DownloadBSC_OnLowResource, 00267 DownloadBSC_OnProgress, 00268 DownloadBSC_OnStopBinding, 00269 DownloadBSC_GetBindInfo, 00270 DownloadBSC_OnDataAvailable, 00271 DownloadBSC_OnObjectAvailable 00272 }; 00273 00274 static HRESULT WINAPI DwlServiceProvider_QueryInterface(IServiceProvider *iface, 00275 REFIID riid, void **ppv) 00276 { 00277 DownloadBSC *This = impl_from_IServiceProvider(iface); 00278 return IBindStatusCallback_QueryInterface(&This->IBindStatusCallback_iface, riid, ppv); 00279 } 00280 00281 static ULONG WINAPI DwlServiceProvider_AddRef(IServiceProvider *iface) 00282 { 00283 DownloadBSC *This = impl_from_IServiceProvider(iface); 00284 return IBindStatusCallback_AddRef(&This->IBindStatusCallback_iface); 00285 } 00286 00287 static ULONG WINAPI DwlServiceProvider_Release(IServiceProvider *iface) 00288 { 00289 DownloadBSC *This = impl_from_IServiceProvider(iface); 00290 return IBindStatusCallback_Release(&This->IBindStatusCallback_iface); 00291 } 00292 00293 static HRESULT WINAPI DwlServiceProvider_QueryService(IServiceProvider *iface, 00294 REFGUID guidService, REFIID riid, void **ppv) 00295 { 00296 DownloadBSC *This = impl_from_IServiceProvider(iface); 00297 IServiceProvider *serv_prov; 00298 HRESULT hres; 00299 00300 TRACE("(%p)->(%s %s %p)\n", This, debugstr_guid(guidService), debugstr_guid(riid), ppv); 00301 00302 if(!This->callback) 00303 return E_NOINTERFACE; 00304 00305 hres = IBindStatusCallback_QueryInterface(This->callback, riid, ppv); 00306 if(SUCCEEDED(hres)) 00307 return S_OK; 00308 00309 hres = IBindStatusCallback_QueryInterface(This->callback, &IID_IServiceProvider, (void**)&serv_prov); 00310 if(SUCCEEDED(hres)) { 00311 hres = IServiceProvider_QueryService(serv_prov, guidService, riid, ppv); 00312 IServiceProvider_Release(serv_prov); 00313 return hres; 00314 } 00315 00316 return E_NOINTERFACE; 00317 } 00318 00319 static const IServiceProviderVtbl ServiceProviderVtbl = { 00320 DwlServiceProvider_QueryInterface, 00321 DwlServiceProvider_AddRef, 00322 DwlServiceProvider_Release, 00323 DwlServiceProvider_QueryService 00324 }; 00325 00326 static HRESULT DownloadBSC_Create(IBindStatusCallback *callback, LPCWSTR file_name, IBindStatusCallback **ret_callback) 00327 { 00328 DownloadBSC *ret = heap_alloc(sizeof(*ret)); 00329 00330 ret->IBindStatusCallback_iface.lpVtbl = &BindStatusCallbackVtbl; 00331 ret->IServiceProvider_iface.lpVtbl = &ServiceProviderVtbl; 00332 ret->ref = 1; 00333 ret->file_name = heap_strdupW(file_name); 00334 ret->cache_file = NULL; 00335 ret->binding = NULL; 00336 00337 if(callback) 00338 IBindStatusCallback_AddRef(callback); 00339 ret->callback = callback; 00340 00341 *ret_callback = &ret->IBindStatusCallback_iface; 00342 return S_OK; 00343 } 00344 00345 HRESULT create_default_callback(IBindStatusCallback **ret) 00346 { 00347 IBindStatusCallback *callback; 00348 HRESULT hres; 00349 00350 hres = DownloadBSC_Create(NULL, NULL, &callback); 00351 if(FAILED(hres)) 00352 return hres; 00353 00354 hres = wrap_callback(callback, ret); 00355 IBindStatusCallback_Release(callback); 00356 return hres; 00357 } 00358 00359 /*********************************************************************** 00360 * URLDownloadToFileW (URLMON.@) 00361 * 00362 * Downloads URL szURL to file szFileName and call lpfnCB callback to 00363 * report progress. 00364 * 00365 * PARAMS 00366 * pCaller [I] controlling IUnknown interface. 00367 * szURL [I] URL of the file to download 00368 * szFileName [I] file name to store the content of the URL 00369 * dwReserved [I] reserved - set to 0 00370 * lpfnCB [I] callback for progress report 00371 * 00372 * RETURNS 00373 * S_OK on success 00374 */ 00375 HRESULT WINAPI URLDownloadToFileW(LPUNKNOWN pCaller, LPCWSTR szURL, LPCWSTR szFileName, 00376 DWORD dwReserved, LPBINDSTATUSCALLBACK lpfnCB) 00377 { 00378 IBindStatusCallback *callback; 00379 IUnknown *unk; 00380 IMoniker *mon; 00381 IBindCtx *bindctx; 00382 HRESULT hres; 00383 00384 TRACE("(%p %s %s %d %p)\n", pCaller, debugstr_w(szURL), debugstr_w(szFileName), dwReserved, lpfnCB); 00385 00386 if(pCaller) 00387 FIXME("pCaller not supported\n"); 00388 00389 hres = DownloadBSC_Create(lpfnCB, szFileName, &callback); 00390 if(FAILED(hres)) 00391 return hres; 00392 00393 hres = CreateAsyncBindCtx(0, callback, NULL, &bindctx); 00394 IBindStatusCallback_Release(callback); 00395 if(FAILED(hres)) 00396 return hres; 00397 00398 hres = CreateURLMoniker(NULL, szURL, &mon); 00399 if(FAILED(hres)) { 00400 IBindCtx_Release(bindctx); 00401 return hres; 00402 } 00403 00404 hres = IMoniker_BindToStorage(mon, bindctx, NULL, &IID_IUnknown, (void**)&unk); 00405 IMoniker_Release(mon); 00406 IBindCtx_Release(bindctx); 00407 00408 if(unk) 00409 IUnknown_Release(unk); 00410 00411 return hres == MK_S_ASYNCHRONOUS ? S_OK : hres; 00412 } 00413 00414 /*********************************************************************** 00415 * URLDownloadToFileA (URLMON.@) 00416 * 00417 * Downloads URL szURL to rile szFileName and call lpfnCB callback to 00418 * report progress. 00419 * 00420 * PARAMS 00421 * pCaller [I] controlling IUnknown interface. 00422 * szURL [I] URL of the file to download 00423 * szFileName [I] file name to store the content of the URL 00424 * dwReserved [I] reserved - set to 0 00425 * lpfnCB [I] callback for progress report 00426 * 00427 * RETURNS 00428 * S_OK on success 00429 */ 00430 HRESULT WINAPI URLDownloadToFileA(LPUNKNOWN pCaller, LPCSTR szURL, LPCSTR szFileName, DWORD dwReserved, 00431 LPBINDSTATUSCALLBACK lpfnCB) 00432 { 00433 LPWSTR urlW, file_nameW; 00434 HRESULT hres; 00435 00436 TRACE("(%p %s %s %d %p)\n", pCaller, debugstr_a(szURL), debugstr_a(szFileName), dwReserved, lpfnCB); 00437 00438 urlW = heap_strdupAtoW(szURL); 00439 file_nameW = heap_strdupAtoW(szFileName); 00440 00441 hres = URLDownloadToFileW(pCaller, urlW, file_nameW, dwReserved, lpfnCB); 00442 00443 heap_free(urlW); 00444 heap_free(file_nameW); 00445 00446 return hres; 00447 } Generated on Sun May 27 2012 04:21:35 for ReactOS by
1.7.6.1
|