ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

download.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.