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

bsc.c
Go to the documentation of this file.
00001 /*
00002  * Copyright 2008 Piotr Caban
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 #define COBJMACROS
00020 #define NONAMELESSUNION
00021 
00022 #include "config.h"
00023 
00024 #include <stdarg.h>
00025 #include <assert.h>
00026 #include "windef.h"
00027 #include "winbase.h"
00028 #include "winuser.h"
00029 #include "ole2.h"
00030 #include "msxml2.h"
00031 #include "wininet.h"
00032 #include "urlmon.h"
00033 #include "winreg.h"
00034 #include "shlwapi.h"
00035 
00036 #include "wine/debug.h"
00037 
00038 #include "msxml_private.h"
00039 
00040 WINE_DEFAULT_DEBUG_CHANNEL(msxml);
00041 
00042 struct bsc_t {
00043     const struct IBindStatusCallbackVtbl *lpVtbl;
00044 
00045     LONG ref;
00046 
00047     void *obj;
00048     HRESULT (*onDataAvailable)(void*,char*,DWORD);
00049 
00050     IBinding *binding;
00051     IStream *memstream;
00052 };
00053 
00054 static inline bsc_t *impl_from_IBindStatusCallback( IBindStatusCallback *iface )
00055 {
00056     return (bsc_t *)((char*)iface - FIELD_OFFSET(bsc_t, lpVtbl));
00057 }
00058 
00059 static HRESULT WINAPI bsc_QueryInterface(
00060     IBindStatusCallback *iface,
00061     REFIID riid,
00062     LPVOID *ppobj )
00063 {
00064     if (IsEqualGUID(riid, &IID_IUnknown) ||
00065         IsEqualGUID(riid, &IID_IBindStatusCallback))
00066     {
00067         IBindStatusCallback_AddRef( iface );
00068         *ppobj = iface;
00069         return S_OK;
00070     }
00071 
00072     TRACE("interface %s not implemented\n", debugstr_guid(riid));
00073     return E_NOINTERFACE;
00074 }
00075 
00076 static ULONG WINAPI bsc_AddRef(
00077     IBindStatusCallback *iface )
00078 {
00079     bsc_t *This = impl_from_IBindStatusCallback(iface);
00080     LONG ref = InterlockedIncrement(&This->ref);
00081 
00082     TRACE("(%p) ref=%d\n", This, ref);
00083 
00084     return ref;
00085 }
00086 
00087 static ULONG WINAPI bsc_Release(
00088     IBindStatusCallback *iface )
00089 {
00090     bsc_t *This = impl_from_IBindStatusCallback(iface);
00091     LONG ref = InterlockedDecrement(&This->ref);
00092 
00093     TRACE("(%p) ref=%d\n", This, ref);
00094 
00095     if(!ref) {
00096         if (This->binding)   IBinding_Release(This->binding);
00097         if (This->memstream) IStream_Release(This->memstream);
00098         heap_free(This);
00099     }
00100 
00101     return ref;
00102 }
00103 
00104 static HRESULT WINAPI bsc_OnStartBinding(
00105         IBindStatusCallback* iface,
00106         DWORD dwReserved,
00107         IBinding* pib)
00108 {
00109     bsc_t *This = impl_from_IBindStatusCallback(iface);
00110     HRESULT hr;
00111 
00112     TRACE("(%p)->(%x %p)\n", This, dwReserved, pib);
00113 
00114     This->binding = pib;
00115     IBinding_AddRef(pib);
00116 
00117     hr = CreateStreamOnHGlobal(NULL, TRUE, &This->memstream);
00118     if(FAILED(hr))
00119         return hr;
00120 
00121     return S_OK;
00122 }
00123 
00124 static HRESULT WINAPI bsc_GetPriority(
00125         IBindStatusCallback* iface,
00126         LONG* pnPriority)
00127 {
00128     return S_OK;
00129 }
00130 
00131 static HRESULT WINAPI bsc_OnLowResource(
00132         IBindStatusCallback* iface,
00133         DWORD reserved)
00134 {
00135     return S_OK;
00136 }
00137 
00138 static HRESULT WINAPI bsc_OnProgress(
00139         IBindStatusCallback* iface,
00140         ULONG ulProgress,
00141         ULONG ulProgressMax,
00142         ULONG ulStatusCode,
00143         LPCWSTR szStatusText)
00144 {
00145     return S_OK;
00146 }
00147 
00148 static HRESULT WINAPI bsc_OnStopBinding(
00149         IBindStatusCallback* iface,
00150         HRESULT hresult,
00151         LPCWSTR szError)
00152 {
00153     bsc_t *This = impl_from_IBindStatusCallback(iface);
00154     HRESULT hr = S_OK;
00155 
00156     TRACE("(%p)->(%08x %s)\n", This, hresult, debugstr_w(szError));
00157 
00158     if(This->binding) {
00159         IBinding_Release(This->binding);
00160         This->binding = NULL;
00161     }
00162 
00163     if(This->obj && SUCCEEDED(hresult)) {
00164         HGLOBAL hglobal;
00165         hr = GetHGlobalFromStream(This->memstream, &hglobal);
00166         if(SUCCEEDED(hr))
00167         {
00168             DWORD len = GlobalSize(hglobal);
00169             char *ptr = GlobalLock(hglobal);
00170 
00171             hr = This->onDataAvailable(This->obj, ptr, len);
00172 
00173             GlobalUnlock(hglobal);
00174         }
00175     }
00176 
00177     return hr;
00178 }
00179 
00180 static HRESULT WINAPI bsc_GetBindInfo(
00181         IBindStatusCallback* iface,
00182         DWORD* grfBINDF,
00183         BINDINFO* pbindinfo)
00184 {
00185     *grfBINDF = BINDF_GETNEWESTVERSION|BINDF_PULLDATA|BINDF_RESYNCHRONIZE|BINDF_PRAGMA_NO_CACHE;
00186 
00187     return S_OK;
00188 }
00189 
00190 static HRESULT WINAPI bsc_OnDataAvailable(
00191         IBindStatusCallback* iface,
00192         DWORD grfBSCF,
00193         DWORD dwSize,
00194         FORMATETC* pformatetc,
00195         STGMEDIUM* pstgmed)
00196 {
00197     bsc_t *This = impl_from_IBindStatusCallback(iface);
00198     BYTE buf[4096];
00199     DWORD read, written;
00200     HRESULT hr;
00201 
00202     TRACE("(%p)->(%x %d %p %p)\n", This, grfBSCF, dwSize, pformatetc, pstgmed);
00203 
00204     do
00205     {
00206         hr = IStream_Read(pstgmed->u.pstm, buf, sizeof(buf), &read);
00207         if(FAILED(hr))
00208             break;
00209 
00210         hr = IStream_Write(This->memstream, buf, read, &written);
00211     } while(SUCCEEDED(hr) && written != 0 && read != 0);
00212 
00213     return S_OK;
00214 }
00215 
00216 static HRESULT WINAPI bsc_OnObjectAvailable(
00217         IBindStatusCallback* iface,
00218         REFIID riid,
00219         IUnknown* punk)
00220 {
00221     return S_OK;
00222 }
00223 
00224 static const struct IBindStatusCallbackVtbl bsc_vtbl =
00225 {
00226     bsc_QueryInterface,
00227     bsc_AddRef,
00228     bsc_Release,
00229     bsc_OnStartBinding,
00230     bsc_GetPriority,
00231     bsc_OnLowResource,
00232     bsc_OnProgress,
00233     bsc_OnStopBinding,
00234     bsc_GetBindInfo,
00235     bsc_OnDataAvailable,
00236     bsc_OnObjectAvailable
00237 };
00238 
00239 HRESULT bind_url(LPCWSTR url, HRESULT (*onDataAvailable)(void*,char*,DWORD), void *obj, bsc_t **ret)
00240 {
00241     WCHAR fileUrl[INTERNET_MAX_URL_LENGTH];
00242     bsc_t *bsc;
00243     IBindCtx *pbc;
00244     HRESULT hr;
00245 
00246     TRACE("%s\n", debugstr_w(url));
00247 
00248     if(!PathIsURLW(url))
00249     {
00250         WCHAR fullpath[MAX_PATH];
00251         DWORD needed = sizeof(fileUrl)/sizeof(WCHAR);
00252 
00253         if(!PathSearchAndQualifyW(url, fullpath, sizeof(fullpath)/sizeof(WCHAR)))
00254         {
00255             WARN("can't find path\n");
00256             return E_FAIL;
00257         }
00258 
00259         if(FAILED(UrlCreateFromPathW(url, fileUrl, &needed, 0)))
00260         {
00261             ERR("can't create url from path\n");
00262             return E_FAIL;
00263         }
00264         url = fileUrl;
00265     }
00266 
00267     hr = CreateBindCtx(0, &pbc);
00268     if(FAILED(hr))
00269         return hr;
00270 
00271     bsc = heap_alloc(sizeof(bsc_t));
00272 
00273     bsc->lpVtbl = &bsc_vtbl;
00274     bsc->ref = 1;
00275     bsc->obj = obj;
00276     bsc->onDataAvailable = onDataAvailable;
00277     bsc->binding = NULL;
00278     bsc->memstream = NULL;
00279 
00280     hr = RegisterBindStatusCallback(pbc, (IBindStatusCallback*)&bsc->lpVtbl, NULL, 0);
00281     if(SUCCEEDED(hr))
00282     {
00283         IMoniker *moniker;
00284 
00285         hr = CreateURLMoniker(NULL, url, &moniker);
00286         if(SUCCEEDED(hr))
00287         {
00288             IStream *stream;
00289             hr = IMoniker_BindToStorage(moniker, pbc, NULL, &IID_IStream, (LPVOID*)&stream);
00290             IMoniker_Release(moniker);
00291             if(stream)
00292                 IStream_Release(stream);
00293         }
00294         IBindCtx_Release(pbc);
00295     }
00296 
00297     if(FAILED(hr))
00298     {
00299         IBindStatusCallback_Release((IBindStatusCallback*)&bsc->lpVtbl);
00300         bsc = NULL;
00301     }
00302 
00303     *ret = bsc;
00304     return hr;
00305 }
00306 
00307 void detach_bsc(bsc_t *bsc)
00308 {
00309     if(bsc->binding)
00310         IBinding_Abort(bsc->binding);
00311 
00312     bsc->obj = NULL;
00313     IBindStatusCallback_Release((IBindStatusCallback*)&bsc->lpVtbl);
00314 }

Generated on Sun May 27 2012 04:25:22 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.