Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenprotocol.c
Go to the documentation of this file.
00001 /* 00002 * Copyright 2005 Jacek 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 #include "config.h" 00020 00021 #include <stdarg.h> 00022 #include <stdio.h> 00023 00024 #define COBJMACROS 00025 00026 #include "windef.h" 00027 #include "winbase.h" 00028 #include "winuser.h" 00029 #include "ole2.h" 00030 00031 #include "wine/debug.h" 00032 #include "wine/unicode.h" 00033 00034 #include "mshtml_private.h" 00035 00036 WINE_DEFAULT_DEBUG_CHANNEL(mshtml); 00037 00038 /******************************************************************** 00039 * common ProtocolFactory implementation 00040 */ 00041 00042 #define CLASSFACTORY(x) (&(x)->lpClassFactoryVtbl) 00043 #define PROTOCOL(x) ((IInternetProtocol*) &(x)->lpInternetProtocolVtbl) 00044 #define PROTOCOLINFO(x) ((IInternetProtocolInfo*) &(x)->lpInternetProtocolInfoVtbl) 00045 00046 typedef struct { 00047 const IInternetProtocolInfoVtbl *lpInternetProtocolInfoVtbl; 00048 const IClassFactoryVtbl *lpClassFactoryVtbl; 00049 } ProtocolFactory; 00050 00051 #define PROTOCOLINFO_THIS(iface) DEFINE_THIS(ProtocolFactory, InternetProtocolInfo, iface) 00052 00053 static HRESULT WINAPI InternetProtocolInfo_QueryInterface(IInternetProtocolInfo *iface, REFIID riid, void **ppv) 00054 { 00055 ProtocolFactory *This = PROTOCOLINFO_THIS(iface); 00056 00057 *ppv = NULL; 00058 if(IsEqualGUID(&IID_IUnknown, riid)) { 00059 TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv); 00060 *ppv = PROTOCOLINFO(This); 00061 }else if(IsEqualGUID(&IID_IInternetProtocolInfo, riid)) { 00062 TRACE("(%p)->(IID_IInternetProtocolInfo %p)\n", This, ppv); 00063 *ppv = PROTOCOLINFO(This); 00064 }else if(IsEqualGUID(&IID_IClassFactory, riid)) { 00065 TRACE("(%p)->(IID_IClassFactory %p)\n", This, ppv); 00066 *ppv = CLASSFACTORY(This); 00067 } 00068 00069 if(!*ppv) { 00070 WARN("unknown interface %s\n", debugstr_guid(riid)); 00071 return E_NOINTERFACE; 00072 } 00073 00074 IInternetProtocolInfo_AddRef(iface); 00075 return S_OK; 00076 } 00077 00078 static ULONG WINAPI InternetProtocolInfo_AddRef(IInternetProtocolInfo *iface) 00079 { 00080 TRACE("(%p)\n", iface); 00081 return 2; 00082 } 00083 00084 static ULONG WINAPI InternetProtocolInfo_Release(IInternetProtocolInfo *iface) 00085 { 00086 TRACE("(%p)\n", iface); 00087 return 1; 00088 } 00089 00090 static HRESULT WINAPI InternetProtocolInfo_CombineUrl(IInternetProtocolInfo *iface, 00091 LPCWSTR pwzBaseUrl, LPCWSTR pwzRelativeUrl, DWORD dwCombineFlags, LPWSTR pwzResult, 00092 DWORD cchResult, DWORD* pcchResult, DWORD dwReserved) 00093 { 00094 TRACE("%p)->(%s %s %08x %p %d %p %d)\n", iface, debugstr_w(pwzBaseUrl), 00095 debugstr_w(pwzRelativeUrl), dwCombineFlags, pwzResult, cchResult, 00096 pcchResult, dwReserved); 00097 00098 return INET_E_USE_DEFAULT_PROTOCOLHANDLER; 00099 } 00100 00101 static HRESULT WINAPI InternetProtocolInfo_CompareUrl(IInternetProtocolInfo *iface, LPCWSTR pwzUrl1, 00102 LPCWSTR pwzUrl2, DWORD dwCompareFlags) 00103 { 00104 TRACE("%p)->(%s %s %08x)\n", iface, debugstr_w(pwzUrl1), debugstr_w(pwzUrl2), dwCompareFlags); 00105 return E_NOTIMPL; 00106 } 00107 00108 #undef PROTOCOLINFO_THIS 00109 00110 #define CLASSFACTORY_THIS(iface) DEFINE_THIS(ProtocolFactory, ClassFactory, iface) 00111 00112 static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv) 00113 { 00114 ProtocolFactory *This = CLASSFACTORY_THIS(iface); 00115 return IInternetProtocolInfo_QueryInterface(PROTOCOLINFO(This), riid, ppv); 00116 } 00117 00118 static ULONG WINAPI ClassFactory_AddRef(IClassFactory *iface) 00119 { 00120 ProtocolFactory *This = CLASSFACTORY_THIS(iface); 00121 return IInternetProtocolInfo_AddRef(PROTOCOLINFO(This)); 00122 } 00123 00124 static ULONG WINAPI ClassFactory_Release(IClassFactory *iface) 00125 { 00126 ProtocolFactory *This = CLASSFACTORY_THIS(iface); 00127 return IInternetProtocolInfo_Release(PROTOCOLINFO(This)); 00128 } 00129 00130 static HRESULT WINAPI ClassFactory_LockServer(IClassFactory *iface, BOOL dolock) 00131 { 00132 TRACE("(%p)->(%x)\n", iface, dolock); 00133 return S_OK; 00134 } 00135 00136 #undef CLASSFACTORY_THIS 00137 00138 /******************************************************************** 00139 * AboutProtocol implementation 00140 */ 00141 00142 typedef struct { 00143 const IInternetProtocolVtbl *lpInternetProtocolVtbl; 00144 00145 LONG ref; 00146 00147 BYTE *data; 00148 ULONG data_len; 00149 ULONG cur; 00150 00151 IUnknown *pUnkOuter; 00152 } AboutProtocol; 00153 00154 #define PROTOCOL_THIS(iface) DEFINE_THIS(AboutProtocol, InternetProtocol, iface) 00155 00156 static HRESULT WINAPI AboutProtocol_QueryInterface(IInternetProtocol *iface, REFIID riid, void **ppv) 00157 { 00158 AboutProtocol *This = PROTOCOL_THIS(iface); 00159 00160 *ppv = NULL; 00161 00162 if(IsEqualGUID(&IID_IUnknown, riid)) { 00163 TRACE("(%p)->(IID_IUnknown %p)\n", iface, ppv); 00164 if(This->pUnkOuter) 00165 return IUnknown_QueryInterface(This->pUnkOuter, riid, ppv); 00166 *ppv = PROTOCOL(This); 00167 }else if(IsEqualGUID(&IID_IInternetProtocolRoot, riid)) { 00168 TRACE("(%p)->(IID_IInternetProtocolRoot %p)\n", iface, ppv); 00169 *ppv = PROTOCOL(This); 00170 }else if(IsEqualGUID(&IID_IInternetProtocol, riid)) { 00171 TRACE("(%p)->(IID_IInternetProtocol %p)\n", iface, ppv); 00172 *ppv = PROTOCOL(This); 00173 }else if(IsEqualGUID(&IID_IServiceProvider, riid)) { 00174 FIXME("IServiceProvider is not implemented\n"); 00175 return E_NOINTERFACE; 00176 } 00177 00178 if(!*ppv) { 00179 TRACE("unknown interface %s\n", debugstr_guid(riid)); 00180 return E_NOINTERFACE; 00181 } 00182 00183 IInternetProtocol_AddRef(iface); 00184 return S_OK; 00185 } 00186 00187 static ULONG WINAPI AboutProtocol_AddRef(IInternetProtocol *iface) 00188 { 00189 AboutProtocol *This = PROTOCOL_THIS(iface); 00190 ULONG ref = InterlockedIncrement(&This->ref); 00191 TRACE("(%p) ref=%d\n", iface, ref); 00192 return This->pUnkOuter ? IUnknown_AddRef(This->pUnkOuter) : ref; 00193 } 00194 00195 static ULONG WINAPI AboutProtocol_Release(IInternetProtocol *iface) 00196 { 00197 AboutProtocol *This = PROTOCOL_THIS(iface); 00198 IUnknown *pUnkOuter = This->pUnkOuter; 00199 ULONG ref = InterlockedDecrement(&This->ref); 00200 00201 TRACE("(%p) ref=%x\n", iface, ref); 00202 00203 if(!ref) { 00204 heap_free(This->data); 00205 heap_free(This); 00206 } 00207 00208 return pUnkOuter ? IUnknown_Release(pUnkOuter) : ref; 00209 } 00210 00211 static HRESULT WINAPI AboutProtocol_Start(IInternetProtocol *iface, LPCWSTR szUrl, 00212 IInternetProtocolSink* pOIProtSink, IInternetBindInfo* pOIBindInfo, 00213 DWORD grfPI, HANDLE_PTR dwReserved) 00214 { 00215 AboutProtocol *This = PROTOCOL_THIS(iface); 00216 BINDINFO bindinfo; 00217 DWORD grfBINDF = 0; 00218 LPCWSTR text = NULL; 00219 00220 static const WCHAR html_begin[] = {0xfeff,'<','H','T','M','L','>',0}; 00221 static const WCHAR html_end[] = {'<','/','H','T','M','L','>',0}; 00222 static const WCHAR wszBlank[] = {'b','l','a','n','k',0}; 00223 static const WCHAR wszAbout[] = {'a','b','o','u','t',':'}; 00224 static const WCHAR wszTextHtml[] = {'t','e','x','t','/','h','t','m','l',0}; 00225 00226 /* NOTE: 00227 * the about protocol seems not to work as I would expect. It creates html document 00228 * for a given url, eg. about:some_text -> <HTML>some_text</HTML> except for the case when 00229 * some_text = "blank", when document is blank (<HTML></HMTL>). The same happens 00230 * when the url does not have "about:" in the beginning. 00231 */ 00232 00233 TRACE("(%p)->(%s %p %p %08x %lx)\n", This, debugstr_w(szUrl), pOIProtSink, 00234 pOIBindInfo, grfPI, dwReserved); 00235 00236 memset(&bindinfo, 0, sizeof(bindinfo)); 00237 bindinfo.cbSize = sizeof(BINDINFO); 00238 IInternetBindInfo_GetBindInfo(pOIBindInfo, &grfBINDF, &bindinfo); 00239 ReleaseBindInfo(&bindinfo); 00240 00241 TRACE("bindf %x\n", grfBINDF); 00242 00243 if(strlenW(szUrl)>=sizeof(wszAbout)/sizeof(WCHAR) && !memcmp(wszAbout, szUrl, sizeof(wszAbout))) { 00244 text = szUrl + sizeof(wszAbout)/sizeof(WCHAR); 00245 if(!strcmpW(wszBlank, text)) 00246 text = NULL; 00247 } 00248 00249 This->data_len = sizeof(html_begin)+sizeof(html_end)-sizeof(WCHAR) 00250 + (text ? strlenW(text)*sizeof(WCHAR) : 0); 00251 This->data = heap_alloc(This->data_len); 00252 00253 memcpy(This->data, html_begin, sizeof(html_begin)); 00254 if(text) 00255 strcatW((LPWSTR)This->data, text); 00256 strcatW((LPWSTR)This->data, html_end); 00257 00258 This->cur = 0; 00259 00260 IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_MIMETYPEAVAILABLE, wszTextHtml); 00261 00262 IInternetProtocolSink_ReportData(pOIProtSink, 00263 BSCF_FIRSTDATANOTIFICATION | BSCF_LASTDATANOTIFICATION | BSCF_DATAFULLYAVAILABLE, 00264 This->data_len, This->data_len); 00265 00266 IInternetProtocolSink_ReportResult(pOIProtSink, S_OK, 0, NULL); 00267 00268 return S_OK; 00269 } 00270 00271 static HRESULT WINAPI AboutProtocol_Continue(IInternetProtocol *iface, PROTOCOLDATA* pProtocolData) 00272 { 00273 AboutProtocol *This = PROTOCOL_THIS(iface); 00274 FIXME("(%p)->(%p)\n", This, pProtocolData); 00275 return E_NOTIMPL; 00276 } 00277 00278 static HRESULT WINAPI AboutProtocol_Abort(IInternetProtocol *iface, HRESULT hrReason, 00279 DWORD dwOptions) 00280 { 00281 AboutProtocol *This = PROTOCOL_THIS(iface); 00282 FIXME("(%p)->(%08x %08x)\n", This, hrReason, dwOptions); 00283 return E_NOTIMPL; 00284 } 00285 00286 static HRESULT WINAPI AboutProtocol_Terminate(IInternetProtocol *iface, DWORD dwOptions) 00287 { 00288 AboutProtocol *This = PROTOCOL_THIS(iface); 00289 TRACE("(%p)->(%08x)\n", This, dwOptions); 00290 return S_OK; 00291 } 00292 00293 static HRESULT WINAPI AboutProtocol_Suspend(IInternetProtocol *iface) 00294 { 00295 AboutProtocol *This = PROTOCOL_THIS(iface); 00296 FIXME("(%p)\n", This); 00297 return E_NOTIMPL; 00298 } 00299 00300 static HRESULT WINAPI AboutProtocol_Resume(IInternetProtocol *iface) 00301 { 00302 AboutProtocol *This = PROTOCOL_THIS(iface); 00303 FIXME("(%p)\n", This); 00304 return E_NOTIMPL; 00305 } 00306 00307 static HRESULT WINAPI AboutProtocol_Read(IInternetProtocol *iface, void* pv, ULONG cb, ULONG* pcbRead) 00308 { 00309 AboutProtocol *This = PROTOCOL_THIS(iface); 00310 00311 TRACE("(%p)->(%p %u %p)\n", This, pv, cb, pcbRead); 00312 00313 if(!This->data) 00314 return E_FAIL; 00315 00316 *pcbRead = (cb > This->data_len-This->cur ? This->data_len-This->cur : cb); 00317 00318 if(!*pcbRead) 00319 return S_FALSE; 00320 00321 memcpy(pv, This->data+This->cur, *pcbRead); 00322 This->cur += *pcbRead; 00323 00324 return S_OK; 00325 } 00326 00327 static HRESULT WINAPI AboutProtocol_Seek(IInternetProtocol *iface, LARGE_INTEGER dlibMove, 00328 DWORD dwOrigin, ULARGE_INTEGER* plibNewPosition) 00329 { 00330 AboutProtocol *This = PROTOCOL_THIS(iface); 00331 FIXME("(%p)->(%d %d %p)\n", This, dlibMove.u.LowPart, dwOrigin, plibNewPosition); 00332 return E_NOTIMPL; 00333 } 00334 00335 static HRESULT WINAPI AboutProtocol_LockRequest(IInternetProtocol *iface, DWORD dwOptions) 00336 { 00337 AboutProtocol *This = PROTOCOL_THIS(iface); 00338 00339 TRACE("(%p)->(%d)\n", This, dwOptions); 00340 00341 return S_OK; 00342 } 00343 00344 static HRESULT WINAPI AboutProtocol_UnlockRequest(IInternetProtocol *iface) 00345 { 00346 AboutProtocol *This = PROTOCOL_THIS(iface); 00347 00348 TRACE("(%p)\n", This); 00349 00350 return S_OK; 00351 } 00352 00353 #undef PROTOCOL_THIS 00354 00355 static const IInternetProtocolVtbl AboutProtocolVtbl = { 00356 AboutProtocol_QueryInterface, 00357 AboutProtocol_AddRef, 00358 AboutProtocol_Release, 00359 AboutProtocol_Start, 00360 AboutProtocol_Continue, 00361 AboutProtocol_Abort, 00362 AboutProtocol_Terminate, 00363 AboutProtocol_Suspend, 00364 AboutProtocol_Resume, 00365 AboutProtocol_Read, 00366 AboutProtocol_Seek, 00367 AboutProtocol_LockRequest, 00368 AboutProtocol_UnlockRequest 00369 }; 00370 00371 static HRESULT WINAPI AboutProtocolFactory_CreateInstance(IClassFactory *iface, IUnknown *pUnkOuter, 00372 REFIID riid, void **ppv) 00373 { 00374 AboutProtocol *ret; 00375 HRESULT hres = S_OK; 00376 00377 TRACE("(%p)->(%p %s %p)\n", iface, pUnkOuter, debugstr_guid(riid), ppv); 00378 00379 ret = heap_alloc(sizeof(AboutProtocol)); 00380 ret->lpInternetProtocolVtbl = &AboutProtocolVtbl; 00381 ret->ref = 0; 00382 00383 ret->data = NULL; 00384 ret->data_len = 0; 00385 ret->cur = 0; 00386 ret->pUnkOuter = pUnkOuter; 00387 00388 if(pUnkOuter) { 00389 ret->ref = 1; 00390 if(IsEqualGUID(&IID_IUnknown, riid)) 00391 *ppv = PROTOCOL(ret); 00392 else 00393 hres = E_INVALIDARG; 00394 }else { 00395 hres = IInternetProtocol_QueryInterface(PROTOCOL(ret), riid, ppv); 00396 } 00397 00398 if(FAILED(hres)) 00399 heap_free(ret); 00400 00401 return hres; 00402 } 00403 00404 static HRESULT WINAPI AboutProtocolInfo_ParseUrl(IInternetProtocolInfo *iface, LPCWSTR pwzUrl, 00405 PARSEACTION ParseAction, DWORD dwParseFlags, LPWSTR pwzResult, DWORD cchResult, 00406 DWORD* pcchResult, DWORD dwReserved) 00407 { 00408 TRACE("%p)->(%s %08x %08x %p %d %p %d)\n", iface, debugstr_w(pwzUrl), ParseAction, 00409 dwParseFlags, pwzResult, cchResult, pcchResult, dwReserved); 00410 00411 if(ParseAction == PARSE_SECURITY_URL) { 00412 unsigned int len = strlenW(pwzUrl); 00413 00414 if(len >= cchResult) 00415 return S_FALSE; 00416 00417 memcpy(pwzResult, pwzUrl, (len+1)*sizeof(WCHAR)); 00418 return S_OK; 00419 } 00420 00421 if(ParseAction == PARSE_DOMAIN) { 00422 if(!pcchResult) 00423 return E_POINTER; 00424 00425 if(pwzUrl) 00426 *pcchResult = strlenW(pwzUrl)+1; 00427 else 00428 *pcchResult = 1; 00429 return E_FAIL; 00430 } 00431 00432 return INET_E_DEFAULT_ACTION; 00433 } 00434 00435 static HRESULT WINAPI AboutProtocolInfo_QueryInfo(IInternetProtocolInfo *iface, LPCWSTR pwzUrl, 00436 QUERYOPTION QueryOption, DWORD dwQueryFlags, LPVOID pBuffer, DWORD cbBuffer, DWORD* pcbBuf, 00437 DWORD dwReserved) 00438 { 00439 TRACE("%p)->(%s %08x %08x %p %d %p %d)\n", iface, debugstr_w(pwzUrl), QueryOption, dwQueryFlags, pBuffer, 00440 cbBuffer, pcbBuf, dwReserved); 00441 00442 switch(QueryOption) { 00443 case QUERY_CAN_NAVIGATE: 00444 return INET_E_USE_DEFAULT_PROTOCOLHANDLER; 00445 00446 case QUERY_USES_NETWORK: 00447 if(!pBuffer || cbBuffer < sizeof(DWORD)) 00448 return E_FAIL; 00449 00450 *(DWORD*)pBuffer = 0; 00451 if(pcbBuf) 00452 *pcbBuf = sizeof(DWORD); 00453 00454 break; 00455 00456 case QUERY_IS_CACHED: 00457 FIXME("Unsupported option QUERY_IS_CACHED\n"); 00458 return E_NOTIMPL; 00459 case QUERY_IS_INSTALLEDENTRY: 00460 FIXME("Unsupported option QUERY_IS_INSTALLEDENTRY\n"); 00461 return E_NOTIMPL; 00462 case QUERY_IS_CACHED_OR_MAPPED: 00463 FIXME("Unsupported option QUERY_IS_CACHED_OR_MAPPED\n"); 00464 return E_NOTIMPL; 00465 case QUERY_IS_SECURE: 00466 FIXME("Unsupported option QUERY_IS_SECURE\n"); 00467 return E_NOTIMPL; 00468 case QUERY_IS_SAFE: 00469 FIXME("Unsupported option QUERY_IS_SAFE\n"); 00470 return E_NOTIMPL; 00471 case QUERY_USES_HISTORYFOLDER: 00472 FIXME("Unsupported option QUERY_USES_HISTORYFOLDER\n"); 00473 return E_FAIL; 00474 default: 00475 return E_FAIL; 00476 } 00477 00478 return S_OK; 00479 } 00480 00481 static const IInternetProtocolInfoVtbl AboutProtocolInfoVtbl = { 00482 InternetProtocolInfo_QueryInterface, 00483 InternetProtocolInfo_AddRef, 00484 InternetProtocolInfo_Release, 00485 AboutProtocolInfo_ParseUrl, 00486 InternetProtocolInfo_CombineUrl, 00487 InternetProtocolInfo_CompareUrl, 00488 AboutProtocolInfo_QueryInfo 00489 }; 00490 00491 static const IClassFactoryVtbl AboutProtocolFactoryVtbl = { 00492 ClassFactory_QueryInterface, 00493 ClassFactory_AddRef, 00494 ClassFactory_Release, 00495 AboutProtocolFactory_CreateInstance, 00496 ClassFactory_LockServer 00497 }; 00498 00499 static ProtocolFactory AboutProtocolFactory = { 00500 &AboutProtocolInfoVtbl, 00501 &AboutProtocolFactoryVtbl 00502 }; 00503 00504 /******************************************************************** 00505 * ResProtocol implementation 00506 */ 00507 00508 typedef struct { 00509 const IInternetProtocolVtbl *lpInternetProtocolVtbl; 00510 LONG ref; 00511 00512 BYTE *data; 00513 ULONG data_len; 00514 ULONG cur; 00515 00516 IUnknown *pUnkOuter; 00517 } ResProtocol; 00518 00519 #define PROTOCOL_THIS(iface) DEFINE_THIS(ResProtocol, InternetProtocol, iface) 00520 00521 static HRESULT WINAPI ResProtocol_QueryInterface(IInternetProtocol *iface, REFIID riid, void **ppv) 00522 { 00523 ResProtocol *This = PROTOCOL_THIS(iface); 00524 00525 *ppv = NULL; 00526 00527 if(IsEqualGUID(&IID_IUnknown, riid)) { 00528 TRACE("(%p)->(IID_IUnknown %p)\n", iface, ppv); 00529 if(This->pUnkOuter) 00530 return IUnknown_QueryInterface(This->pUnkOuter, &IID_IUnknown, ppv); 00531 *ppv = PROTOCOL(This); 00532 }else if(IsEqualGUID(&IID_IInternetProtocolRoot, riid)) { 00533 TRACE("(%p)->(IID_IInternetProtocolRoot %p)\n", iface, ppv); 00534 *ppv = PROTOCOL(This); 00535 }else if(IsEqualGUID(&IID_IInternetProtocol, riid)) { 00536 TRACE("(%p)->(IID_IInternetProtocol %p)\n", iface, ppv); 00537 *ppv = PROTOCOL(This); 00538 }else if(IsEqualGUID(&IID_IServiceProvider, riid)) { 00539 FIXME("IServiceProvider is not implemented\n"); 00540 return E_NOINTERFACE; 00541 } 00542 00543 if(!*ppv) { 00544 TRACE("unknown interface %s\n", debugstr_guid(riid)); 00545 return E_NOINTERFACE; 00546 } 00547 00548 IInternetProtocol_AddRef(iface); 00549 return S_OK; 00550 } 00551 00552 static ULONG WINAPI ResProtocol_AddRef(IInternetProtocol *iface) 00553 { 00554 ResProtocol *This = PROTOCOL_THIS(iface); 00555 ULONG ref = InterlockedIncrement(&This->ref); 00556 TRACE("(%p) ref=%d\n", iface, ref); 00557 return This->pUnkOuter ? IUnknown_AddRef(This->pUnkOuter) : ref; 00558 } 00559 00560 static ULONG WINAPI ResProtocol_Release(IInternetProtocol *iface) 00561 { 00562 ResProtocol *This = (ResProtocol*)iface; 00563 IUnknown *pUnkOuter = This->pUnkOuter; 00564 ULONG ref = InterlockedDecrement(&This->ref); 00565 00566 TRACE("(%p) ref=%x\n", iface, ref); 00567 00568 if(!ref) { 00569 heap_free(This->data); 00570 heap_free(This); 00571 } 00572 00573 return pUnkOuter ? IUnknown_Release(pUnkOuter) : ref; 00574 } 00575 00576 static HRESULT WINAPI ResProtocol_Start(IInternetProtocol *iface, LPCWSTR szUrl, 00577 IInternetProtocolSink* pOIProtSink, IInternetBindInfo* pOIBindInfo, 00578 DWORD grfPI, HANDLE_PTR dwReserved) 00579 { 00580 ResProtocol *This = PROTOCOL_THIS(iface); 00581 DWORD grfBINDF = 0, len; 00582 BINDINFO bindinfo; 00583 LPWSTR url_dll, url_file, url, mime, res_type = (LPWSTR)RT_HTML; 00584 HMODULE hdll; 00585 HRSRC src; 00586 HRESULT hres; 00587 00588 static const WCHAR wszRes[] = {'r','e','s',':','/','/'}; 00589 00590 TRACE("(%p)->(%s %p %p %08x %lx)\n", This, debugstr_w(szUrl), pOIProtSink, 00591 pOIBindInfo, grfPI, dwReserved); 00592 00593 memset(&bindinfo, 0, sizeof(bindinfo)); 00594 bindinfo.cbSize = sizeof(BINDINFO); 00595 IInternetBindInfo_GetBindInfo(pOIBindInfo, &grfBINDF, &bindinfo); 00596 ReleaseBindInfo(&bindinfo); 00597 00598 len = strlenW(szUrl)+16; 00599 url = heap_alloc(len*sizeof(WCHAR)); 00600 hres = CoInternetParseUrl(szUrl, PARSE_ENCODE, 0, url, len, &len, 0); 00601 if(FAILED(hres)) { 00602 WARN("CoInternetParseUrl failed: %08x\n", hres); 00603 heap_free(url); 00604 IInternetProtocolSink_ReportResult(pOIProtSink, hres, 0, NULL); 00605 return hres; 00606 } 00607 00608 if(len < sizeof(wszRes)/sizeof(wszRes[0]) || memcmp(url, wszRes, sizeof(wszRes))) { 00609 WARN("Wrong protocol of url: %s\n", debugstr_w(url)); 00610 IInternetProtocolSink_ReportResult(pOIProtSink, E_INVALIDARG, 0, NULL); 00611 heap_free(url); 00612 return E_INVALIDARG; 00613 } 00614 00615 url_dll = url + sizeof(wszRes)/sizeof(wszRes[0]); 00616 if(!(url_file = strrchrW(url_dll, '/'))) { 00617 WARN("wrong url: %s\n", debugstr_w(url)); 00618 IInternetProtocolSink_ReportResult(pOIProtSink, MK_E_SYNTAX, 0, NULL); 00619 heap_free(url); 00620 return MK_E_SYNTAX; 00621 } 00622 00623 *url_file++ = 0; 00624 hdll = LoadLibraryExW(url_dll, NULL, LOAD_LIBRARY_AS_DATAFILE); 00625 if(!hdll) { 00626 if (!(res_type = strrchrW(url_dll, '/'))) { 00627 WARN("Could not open dll: %s\n", debugstr_w(url_dll)); 00628 IInternetProtocolSink_ReportResult(pOIProtSink, HRESULT_FROM_WIN32(GetLastError()), 0, NULL); 00629 heap_free(url); 00630 return HRESULT_FROM_WIN32(GetLastError()); 00631 } 00632 *res_type++ = 0; 00633 00634 hdll = LoadLibraryExW(url_dll, NULL, LOAD_LIBRARY_AS_DATAFILE); 00635 if(!hdll) { 00636 WARN("Could not open dll: %s\n", debugstr_w(url_dll)); 00637 IInternetProtocolSink_ReportResult(pOIProtSink, HRESULT_FROM_WIN32(GetLastError()), 0, NULL); 00638 heap_free(url); 00639 return HRESULT_FROM_WIN32(GetLastError()); 00640 } 00641 } 00642 00643 TRACE("trying to find resource type %s, name %s\n", debugstr_w(res_type), debugstr_w(url_file)); 00644 00645 src = FindResourceW(hdll, url_file, res_type); 00646 if(!src) { 00647 LPWSTR endpoint = NULL; 00648 DWORD file_id = strtolW(url_file, &endpoint, 10); 00649 if(endpoint == url_file+strlenW(url_file)) 00650 src = FindResourceW(hdll, MAKEINTRESOURCEW(file_id), MAKEINTRESOURCEW(RT_HTML)); 00651 00652 if(!src) { 00653 WARN("Could not find resource\n"); 00654 IInternetProtocolSink_ReportResult(pOIProtSink, 00655 HRESULT_FROM_WIN32(GetLastError()), 0, NULL); 00656 heap_free(url); 00657 return HRESULT_FROM_WIN32(GetLastError()); 00658 } 00659 } 00660 00661 if(This->data) { 00662 WARN("data already loaded\n"); 00663 heap_free(This->data); 00664 } 00665 00666 This->data_len = SizeofResource(hdll, src); 00667 This->data = heap_alloc(This->data_len); 00668 memcpy(This->data, LoadResource(hdll, src), This->data_len); 00669 This->cur = 0; 00670 00671 FreeLibrary(hdll); 00672 00673 hres = FindMimeFromData(NULL, url_file, This->data, This->data_len, NULL, 0, &mime, 0); 00674 heap_free(url); 00675 if(SUCCEEDED(hres)) { 00676 IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_MIMETYPEAVAILABLE, mime); 00677 CoTaskMemFree(mime); 00678 } 00679 00680 IInternetProtocolSink_ReportData(pOIProtSink, 00681 BSCF_FIRSTDATANOTIFICATION | BSCF_LASTDATANOTIFICATION | BSCF_DATAFULLYAVAILABLE, 00682 This->data_len, This->data_len); 00683 00684 IInternetProtocolSink_ReportResult(pOIProtSink, S_OK, 0, NULL); 00685 00686 return S_OK; 00687 } 00688 00689 static HRESULT WINAPI ResProtocol_Continue(IInternetProtocol *iface, PROTOCOLDATA* pProtocolData) 00690 { 00691 ResProtocol *This = PROTOCOL_THIS(iface); 00692 FIXME("(%p)->(%p)\n", This, pProtocolData); 00693 return E_NOTIMPL; 00694 } 00695 00696 static HRESULT WINAPI ResProtocol_Abort(IInternetProtocol *iface, HRESULT hrReason, 00697 DWORD dwOptions) 00698 { 00699 ResProtocol *This = PROTOCOL_THIS(iface); 00700 FIXME("(%p)->(%08x %08x)\n", This, hrReason, dwOptions); 00701 return E_NOTIMPL; 00702 } 00703 00704 static HRESULT WINAPI ResProtocol_Terminate(IInternetProtocol *iface, DWORD dwOptions) 00705 { 00706 ResProtocol *This = PROTOCOL_THIS(iface); 00707 00708 TRACE("(%p)->(%08x)\n", This, dwOptions); 00709 00710 /* test show that we don't have to do anything here */ 00711 return S_OK; 00712 } 00713 00714 static HRESULT WINAPI ResProtocol_Suspend(IInternetProtocol *iface) 00715 { 00716 ResProtocol *This = PROTOCOL_THIS(iface); 00717 FIXME("(%p)\n", This); 00718 return E_NOTIMPL; 00719 } 00720 00721 static HRESULT WINAPI ResProtocol_Resume(IInternetProtocol *iface) 00722 { 00723 ResProtocol *This = PROTOCOL_THIS(iface); 00724 FIXME("(%p)\n", This); 00725 return E_NOTIMPL; 00726 } 00727 00728 static HRESULT WINAPI ResProtocol_Read(IInternetProtocol *iface, void* pv, ULONG cb, ULONG* pcbRead) 00729 { 00730 ResProtocol *This = PROTOCOL_THIS(iface); 00731 00732 TRACE("(%p)->(%p %u %p)\n", This, pv, cb, pcbRead); 00733 00734 if(!This->data) 00735 return E_FAIL; 00736 00737 *pcbRead = (cb > This->data_len-This->cur ? This->data_len-This->cur : cb); 00738 00739 if(!*pcbRead) 00740 return S_FALSE; 00741 00742 memcpy(pv, This->data+This->cur, *pcbRead); 00743 This->cur += *pcbRead; 00744 00745 return S_OK; 00746 } 00747 00748 static HRESULT WINAPI ResProtocol_Seek(IInternetProtocol *iface, LARGE_INTEGER dlibMove, 00749 DWORD dwOrigin, ULARGE_INTEGER* plibNewPosition) 00750 { 00751 ResProtocol *This = PROTOCOL_THIS(iface); 00752 FIXME("(%p)->(%d %d %p)\n", This, dlibMove.u.LowPart, dwOrigin, plibNewPosition); 00753 return E_NOTIMPL; 00754 } 00755 00756 static HRESULT WINAPI ResProtocol_LockRequest(IInternetProtocol *iface, DWORD dwOptions) 00757 { 00758 ResProtocol *This = PROTOCOL_THIS(iface); 00759 00760 TRACE("(%p)->(%d)\n", This, dwOptions); 00761 00762 /* test show that we don't have to do anything here */ 00763 return S_OK; 00764 } 00765 00766 static HRESULT WINAPI ResProtocol_UnlockRequest(IInternetProtocol *iface) 00767 { 00768 ResProtocol *This = PROTOCOL_THIS(iface); 00769 00770 TRACE("(%p)\n", This); 00771 00772 /* test show that we don't have to do anything here */ 00773 return S_OK; 00774 } 00775 00776 #undef PROTOCOL_THIS 00777 00778 static const IInternetProtocolVtbl ResProtocolVtbl = { 00779 ResProtocol_QueryInterface, 00780 ResProtocol_AddRef, 00781 ResProtocol_Release, 00782 ResProtocol_Start, 00783 ResProtocol_Continue, 00784 ResProtocol_Abort, 00785 ResProtocol_Terminate, 00786 ResProtocol_Suspend, 00787 ResProtocol_Resume, 00788 ResProtocol_Read, 00789 ResProtocol_Seek, 00790 ResProtocol_LockRequest, 00791 ResProtocol_UnlockRequest 00792 }; 00793 00794 static HRESULT WINAPI ResProtocolFactory_CreateInstance(IClassFactory *iface, IUnknown *pUnkOuter, 00795 REFIID riid, void **ppv) 00796 { 00797 ResProtocol *ret; 00798 HRESULT hres = S_OK; 00799 00800 TRACE("(%p)->(%p %s %p)\n", iface, pUnkOuter, debugstr_guid(riid), ppv); 00801 00802 ret = heap_alloc(sizeof(ResProtocol)); 00803 ret->lpInternetProtocolVtbl = &ResProtocolVtbl; 00804 ret->ref = 0; 00805 ret->data = NULL; 00806 ret->data_len = 0; 00807 ret->cur = 0; 00808 ret->pUnkOuter = pUnkOuter; 00809 00810 if(pUnkOuter) { 00811 ret->ref = 1; 00812 if(IsEqualGUID(&IID_IUnknown, riid)) 00813 *ppv = PROTOCOL(ret); 00814 else 00815 hres = E_FAIL; 00816 }else { 00817 hres = IInternetProtocol_QueryInterface(PROTOCOL(ret), riid, ppv); 00818 } 00819 00820 if(FAILED(hres)) 00821 heap_free(ret); 00822 00823 return hres; 00824 } 00825 00826 static HRESULT WINAPI ResProtocolInfo_ParseUrl(IInternetProtocolInfo *iface, LPCWSTR pwzUrl, 00827 PARSEACTION ParseAction, DWORD dwParseFlags, LPWSTR pwzResult, DWORD cchResult, 00828 DWORD* pcchResult, DWORD dwReserved) 00829 { 00830 TRACE("%p)->(%s %d %x %p %d %p %d)\n", iface, debugstr_w(pwzUrl), ParseAction, 00831 dwParseFlags, pwzResult, cchResult, pcchResult, dwReserved); 00832 00833 if(ParseAction == PARSE_SECURITY_URL) { 00834 WCHAR file_part[MAX_PATH], full_path[MAX_PATH]; 00835 WCHAR *ptr; 00836 DWORD size, len; 00837 00838 static const WCHAR wszFile[] = {'f','i','l','e',':','/','/'}; 00839 static const WCHAR wszRes[] = {'r','e','s',':','/','/'}; 00840 00841 if(strlenW(pwzUrl) <= sizeof(wszRes)/sizeof(WCHAR) || memcmp(pwzUrl, wszRes, sizeof(wszRes))) 00842 return E_INVALIDARG; 00843 00844 ptr = strchrW(pwzUrl + sizeof(wszRes)/sizeof(WCHAR), '/'); 00845 if(!ptr) 00846 return E_INVALIDARG; 00847 00848 len = ptr - (pwzUrl + sizeof(wszRes)/sizeof(WCHAR)); 00849 if(len >= sizeof(file_part)/sizeof(WCHAR)) { 00850 FIXME("Too long URL\n"); 00851 return MK_E_SYNTAX; 00852 } 00853 00854 memcpy(file_part, pwzUrl + sizeof(wszRes)/sizeof(WCHAR), len*sizeof(WCHAR)); 00855 file_part[len] = 0; 00856 00857 len = SearchPathW(NULL, file_part, NULL, sizeof(full_path)/sizeof(WCHAR), full_path, NULL); 00858 if(!len) { 00859 WARN("Could not find file %s\n", debugstr_w(file_part)); 00860 return MK_E_SYNTAX; 00861 } 00862 00863 size = sizeof(wszFile)/sizeof(WCHAR) + len + 1; 00864 if(pcchResult) 00865 *pcchResult = size; 00866 if(size >= cchResult) 00867 return S_FALSE; 00868 00869 memcpy(pwzResult, wszFile, sizeof(wszFile)); 00870 memcpy(pwzResult + sizeof(wszFile)/sizeof(WCHAR), full_path, (len+1)*sizeof(WCHAR)); 00871 return S_OK; 00872 } 00873 00874 if(ParseAction == PARSE_DOMAIN) { 00875 if(!pcchResult) 00876 return E_POINTER; 00877 00878 if(pwzUrl) 00879 *pcchResult = strlenW(pwzUrl)+1; 00880 else 00881 *pcchResult = 1; 00882 return E_FAIL; 00883 } 00884 00885 return INET_E_DEFAULT_ACTION; 00886 } 00887 00888 static HRESULT WINAPI ResProtocolInfo_QueryInfo(IInternetProtocolInfo *iface, LPCWSTR pwzUrl, 00889 QUERYOPTION QueryOption, DWORD dwQueryFlags, LPVOID pBuffer, DWORD cbBuffer, DWORD* pcbBuf, 00890 DWORD dwReserved) 00891 { 00892 TRACE("%p)->(%s %08x %08x %p %d %p %d)\n", iface, debugstr_w(pwzUrl), QueryOption, dwQueryFlags, pBuffer, 00893 cbBuffer, pcbBuf, dwReserved); 00894 00895 switch(QueryOption) { 00896 case QUERY_USES_NETWORK: 00897 if(!pBuffer || cbBuffer < sizeof(DWORD)) 00898 return E_FAIL; 00899 00900 *(DWORD*)pBuffer = 0; 00901 if(pcbBuf) 00902 *pcbBuf = sizeof(DWORD); 00903 break; 00904 00905 case QUERY_IS_SECURE: 00906 FIXME("not supporte QUERY_IS_SECURE\n"); 00907 return E_NOTIMPL; 00908 case QUERY_IS_SAFE: 00909 FIXME("not supporte QUERY_IS_SAFE\n"); 00910 return E_NOTIMPL; 00911 default: 00912 return INET_E_USE_DEFAULT_PROTOCOLHANDLER; 00913 } 00914 00915 return S_OK; 00916 } 00917 00918 static const IInternetProtocolInfoVtbl ResProtocolInfoVtbl = { 00919 InternetProtocolInfo_QueryInterface, 00920 InternetProtocolInfo_AddRef, 00921 InternetProtocolInfo_Release, 00922 ResProtocolInfo_ParseUrl, 00923 InternetProtocolInfo_CombineUrl, 00924 InternetProtocolInfo_CompareUrl, 00925 ResProtocolInfo_QueryInfo 00926 }; 00927 00928 static const IClassFactoryVtbl ResProtocolFactoryVtbl = { 00929 ClassFactory_QueryInterface, 00930 ClassFactory_AddRef, 00931 ClassFactory_Release, 00932 ResProtocolFactory_CreateInstance, 00933 ClassFactory_LockServer 00934 }; 00935 00936 static ProtocolFactory ResProtocolFactory = { 00937 &ResProtocolInfoVtbl, 00938 &ResProtocolFactoryVtbl 00939 }; 00940 00941 /******************************************************************** 00942 * JSProtocol implementation 00943 */ 00944 00945 static HRESULT WINAPI JSProtocolFactory_CreateInstance(IClassFactory *iface, IUnknown *pUnkOuter, 00946 REFIID riid, void **ppv) 00947 { 00948 FIXME("(%p)->(%p %s %p)\n", iface, pUnkOuter, debugstr_guid(riid), ppv); 00949 return E_NOTIMPL; 00950 } 00951 00952 static HRESULT WINAPI JSProtocolInfo_ParseUrl(IInternetProtocolInfo *iface, LPCWSTR pwzUrl, 00953 PARSEACTION ParseAction, DWORD dwParseFlags, LPWSTR pwzResult, DWORD cchResult, 00954 DWORD* pcchResult, DWORD dwReserved) 00955 { 00956 TRACE("%p)->(%s %d %x %p %d %p %d)\n", iface, debugstr_w(pwzUrl), ParseAction, 00957 dwParseFlags, pwzResult, cchResult, pcchResult, dwReserved); 00958 00959 switch(ParseAction) { 00960 case PARSE_SECURITY_URL: 00961 FIXME("PARSE_SECURITY_URL\n"); 00962 return E_NOTIMPL; 00963 case PARSE_DOMAIN: 00964 FIXME("PARSE_DOMAIN\n"); 00965 return E_NOTIMPL; 00966 default: 00967 return INET_E_DEFAULT_ACTION; 00968 } 00969 00970 return S_OK; 00971 } 00972 00973 static HRESULT WINAPI JSProtocolInfo_QueryInfo(IInternetProtocolInfo *iface, LPCWSTR pwzUrl, 00974 QUERYOPTION QueryOption, DWORD dwQueryFlags, LPVOID pBuffer, DWORD cbBuffer, DWORD* pcbBuf, 00975 DWORD dwReserved) 00976 { 00977 TRACE("%p)->(%s %08x %08x %p %d %p %d)\n", iface, debugstr_w(pwzUrl), QueryOption, dwQueryFlags, pBuffer, 00978 cbBuffer, pcbBuf, dwReserved); 00979 00980 switch(QueryOption) { 00981 case QUERY_USES_NETWORK: 00982 if(!pBuffer || cbBuffer < sizeof(DWORD)) 00983 return E_FAIL; 00984 00985 *(DWORD*)pBuffer = 0; 00986 if(pcbBuf) 00987 *pcbBuf = sizeof(DWORD); 00988 break; 00989 00990 case QUERY_IS_SECURE: 00991 FIXME("not supporte QUERY_IS_SECURE\n"); 00992 return E_NOTIMPL; 00993 00994 default: 00995 return INET_E_USE_DEFAULT_PROTOCOLHANDLER; 00996 } 00997 00998 return S_OK; 00999 } 01000 01001 static const IInternetProtocolInfoVtbl JSProtocolInfoVtbl = { 01002 InternetProtocolInfo_QueryInterface, 01003 InternetProtocolInfo_AddRef, 01004 InternetProtocolInfo_Release, 01005 JSProtocolInfo_ParseUrl, 01006 InternetProtocolInfo_CombineUrl, 01007 InternetProtocolInfo_CompareUrl, 01008 JSProtocolInfo_QueryInfo 01009 }; 01010 01011 static const IClassFactoryVtbl JSProtocolFactoryVtbl = { 01012 ClassFactory_QueryInterface, 01013 ClassFactory_AddRef, 01014 ClassFactory_Release, 01015 JSProtocolFactory_CreateInstance, 01016 ClassFactory_LockServer 01017 }; 01018 01019 static ProtocolFactory JSProtocolFactory = { 01020 &JSProtocolInfoVtbl, 01021 &JSProtocolFactoryVtbl 01022 }; 01023 01024 HRESULT ProtocolFactory_Create(REFCLSID rclsid, REFIID riid, void **ppv) 01025 { 01026 ProtocolFactory *cf = NULL; 01027 01028 if(IsEqualGUID(&CLSID_AboutProtocol, rclsid)) 01029 cf = &AboutProtocolFactory; 01030 else if(IsEqualGUID(&CLSID_ResProtocol, rclsid)) 01031 cf = &ResProtocolFactory; 01032 else if(IsEqualGUID(&CLSID_JSProtocol, rclsid)) 01033 cf = &JSProtocolFactory; 01034 01035 if(!cf) { 01036 FIXME("not implemented protocol %s\n", debugstr_guid(rclsid)); 01037 return CLASS_E_CLASSNOTAVAILABLE; 01038 } 01039 01040 return IUnknown_QueryInterface((IUnknown*)cf, riid, ppv); 01041 } Generated on Sun May 27 2012 04:24:17 for ReactOS by
1.7.6.1
|