Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenbsc.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
1.7.6.1
|