2 * Copyright 2005 Jacek Caban
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
35 #include "wine/debug.h"
36 #include "wine/unicode.h"
38 #include "mshtml_private.h"
40 WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
42 /********************************************************************
43 * common ProtocolFactory implementation
46 #define PROTOCOLINFO(x) ((IInternetProtocolInfo*) &(x)->lpInternetProtocolInfoVtbl)
47 #define CLASSFACTORY(x) ((IClassFactory*) &(x)->lpClassFactoryVtbl)
50 const IInternetProtocolInfoVtbl *lpInternetProtocolInfoVtbl;
51 const IClassFactoryVtbl *lpClassFactoryVtbl;
54 #define PROTOCOLINFO_THIS(iface) DEFINE_THIS(ProtocolFactory, InternetProtocolInfo, iface)
56 static HRESULT WINAPI InternetProtocolInfo_QueryInterface(IInternetProtocolInfo *iface, REFIID riid, void **ppv)
58 ProtocolFactory *This = PROTOCOLINFO_THIS(iface);
61 if(IsEqualGUID(&IID_IUnknown, riid)) {
62 TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
63 *ppv = PROTOCOLINFO(This);
64 }else if(IsEqualGUID(&IID_IInternetProtocolInfo, riid)) {
65 TRACE("(%p)->(IID_IInternetProtocolInfo %p)\n", This, ppv);
66 *ppv = PROTOCOLINFO(This);
67 }else if(IsEqualGUID(&IID_IClassFactory, riid)) {
68 TRACE("(%p)->(IID_IClassFactory %p)\n", This, ppv);
69 *ppv = CLASSFACTORY(This);
73 WARN("unknown interface %s\n", debugstr_guid(riid));
77 IInternetProtocolInfo_AddRef(iface);
81 static ULONG WINAPI InternetProtocolInfo_AddRef(IInternetProtocolInfo *iface)
83 ProtocolFactory *This = PROTOCOLINFO_THIS(iface);
84 TRACE("(%p)\n", This);
89 static ULONG WINAPI InternetProtocolInfo_Release(IInternetProtocolInfo *iface)
91 ProtocolFactory *This = PROTOCOLINFO_THIS(iface);
92 TRACE("(%p)\n", This);
97 #undef PROTOCOLINFO_THIS
99 #define CLASSFACTORY_THIS(iface) DEFINE_THIS(ProtocolFactory, ClassFactory, iface)
101 static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv)
103 ProtocolFactory *This = CLASSFACTORY_THIS(iface);
104 return IInternetProtocolInfo_QueryInterface(PROTOCOLINFO(This), riid, ppv);
107 static ULONG WINAPI ClassFactory_AddRef(IClassFactory *iface)
109 ProtocolFactory *This = CLASSFACTORY_THIS(iface);
110 return IInternetProtocolInfo_AddRef(PROTOCOLINFO(This));
113 static ULONG WINAPI ClassFactory_Release(IClassFactory *iface)
115 ProtocolFactory *This = CLASSFACTORY_THIS(iface);
116 return IInternetProtocolInfo_Release(PROTOCOLINFO(This));
119 static HRESULT WINAPI ClassFactory_LockServer(IClassFactory *iface, BOOL dolock)
121 ProtocolFactory *This = CLASSFACTORY_THIS(iface);
123 TRACE("(%p)->(%x)\n", This, dolock);
133 #undef CLASSFACTORY_THIS
135 /********************************************************************
136 * AboutProtocol implementation
140 const IInternetProtocolVtbl *lpInternetProtocolVtbl;
144 static HRESULT WINAPI AboutProtocol_QueryInterface(IInternetProtocol *iface, REFIID riid, void **ppv)
148 if(IsEqualGUID(&IID_IUnknown, riid)) {
149 TRACE("(%p)->(IID_IUnknown %p)\n", iface, ppv);
151 }else if(IsEqualGUID(&IID_IInternetProtocolRoot, riid)) {
152 TRACE("(%p)->(IID_IInternetProtocolRoot %p)\n", iface, ppv);
154 }else if(IsEqualGUID(&IID_IInternetProtocol, riid)) {
155 TRACE("(%p)->(IID_IInternetProtocol %p)\n", iface, ppv);
157 }else if(IsEqualGUID(&IID_IServiceProvider, riid)) {
158 FIXME("IServiceProvider is not implemented\n");
159 return E_NOINTERFACE;
163 TRACE("unknown interface %s\n", debugstr_guid(riid));
164 return E_NOINTERFACE;
167 IInternetProtocol_AddRef(iface);
171 static ULONG WINAPI AboutProtocol_AddRef(IInternetProtocol *iface)
173 AboutProtocol *This = (AboutProtocol*)iface;
174 ULONG ref = InterlockedIncrement(&This->ref);
175 TRACE("(%p) ref=%ld\n", iface, ref);
179 static ULONG WINAPI AboutProtocol_Release(IInternetProtocol *iface)
181 AboutProtocol *This = (AboutProtocol*)iface;
182 ULONG ref = InterlockedDecrement(&This->ref);
184 TRACE("(%p) ref=%lx\n", iface, ref);
187 HeapFree(GetProcessHeap(), 0, This);
194 static HRESULT WINAPI AboutProtocol_Start(IInternetProtocol *iface, LPCWSTR szUrl,
195 IInternetProtocolSink* pOIProtSink, IInternetBindInfo* pOIBindInfo,
196 DWORD grfPI, DWORD dwReserved)
198 AboutProtocol *This = (AboutProtocol*)iface;
199 FIXME("(%p)->(%s %p %p %08lx %ld)\n", This, debugstr_w(szUrl), pOIProtSink,
200 pOIBindInfo, grfPI, dwReserved);
204 static HRESULT WINAPI AboutProtocol_Continue(IInternetProtocol *iface, PROTOCOLDATA* pProtocolData)
206 AboutProtocol *This = (AboutProtocol*)iface;
207 FIXME("(%p)->(%p)\n", This, pProtocolData);
211 static HRESULT WINAPI AboutProtocol_Abort(IInternetProtocol *iface, HRESULT hrReason,
214 AboutProtocol *This = (AboutProtocol*)iface;
215 FIXME("(%p)->(%08lx %08lx)\n", This, hrReason, dwOptions);
219 static HRESULT WINAPI AboutProtocol_Terminate(IInternetProtocol *iface, DWORD dwOptions)
221 AboutProtocol *This = (AboutProtocol*)iface;
222 FIXME("(%p)->(%08lx)\n", This, dwOptions);
226 static HRESULT WINAPI AboutProtocol_Suspend(IInternetProtocol *iface)
228 AboutProtocol *This = (AboutProtocol*)iface;
229 FIXME("(%p)\n", This);
233 static HRESULT WINAPI AboutProtocol_Resume(IInternetProtocol *iface)
235 AboutProtocol *This = (AboutProtocol*)iface;
236 FIXME("(%p)\n", This);
240 static HRESULT WINAPI AboutProtocol_Read(IInternetProtocol *iface, void* pv, ULONG cb, ULONG* pcbRead)
242 AboutProtocol *This = (AboutProtocol*)iface;
243 FIXME("(%p)->(%lu %p)\n", This, cb, pcbRead);
247 static HRESULT WINAPI AboutProtocol_Seek(IInternetProtocol *iface, LARGE_INTEGER dlibMove,
248 DWORD dwOrigin, ULARGE_INTEGER* plibNewPosition)
250 AboutProtocol *This = (AboutProtocol*)iface;
251 FIXME("(%p)->(%ld %ld %p)\n", This, dlibMove.u.LowPart, dwOrigin, plibNewPosition);
255 static HRESULT WINAPI AboutProtocol_LockRequest(IInternetProtocol *iface, DWORD dwOptions)
257 AboutProtocol *This = (AboutProtocol*)iface;
258 FIXME("(%p)->(%ld)\n", This, dwOptions);
262 static HRESULT WINAPI AboutProtocol_UnlockRequest(IInternetProtocol *iface)
264 AboutProtocol *This = (AboutProtocol*)iface;
265 FIXME("(%p)\n", This);
269 static const IInternetProtocolVtbl AboutProtocolVtbl = {
270 AboutProtocol_QueryInterface,
271 AboutProtocol_AddRef,
272 AboutProtocol_Release,
274 AboutProtocol_Continue,
276 AboutProtocol_Terminate,
277 AboutProtocol_Suspend,
278 AboutProtocol_Resume,
281 AboutProtocol_LockRequest,
282 AboutProtocol_UnlockRequest
285 static HRESULT WINAPI AboutProtocolFactory_CreateInstance(IClassFactory *iface, IUnknown *pUnkOuter,
286 REFIID riid, void **ppv)
291 TRACE("(%p)->(%s %p)\n", iface, debugstr_guid(riid), ppv);
293 ret = HeapAlloc(GetProcessHeap(), 0, sizeof(AboutProtocol));
294 ret->lpInternetProtocolVtbl = &AboutProtocolVtbl;
297 hres = IUnknown_QueryInterface((IUnknown*)ret, riid, ppv);
302 HeapFree(GetProcessHeap(), 0, ret);
307 static HRESULT WINAPI AboutProtocolInfo_ParseUrl(IInternetProtocolInfo *iface, LPCWSTR pwzUrl,
308 PARSEACTION ParseAction, DWORD dwParseFlags, LPWSTR pwzResult, DWORD cchResult,
309 DWORD* pcchResult, DWORD dwReserved)
311 FIXME("%p)->(%s %08x %08lx %p %ld %p %ld)\n", iface, debugstr_w(pwzUrl), ParseAction,
312 dwParseFlags, pwzResult, cchResult, pcchResult, dwReserved);
316 static HRESULT WINAPI AboutProtocolInfo_CombineUrl(IInternetProtocolInfo *iface, LPCWSTR pwzBaseUrl,
317 LPCWSTR pwzRelativeUrl, DWORD dwCombineFlags, LPWSTR pwzResult, DWORD cchResult,
318 DWORD* pcchResult, DWORD dwReserved)
320 FIXME("%p)->(%s %s %08lx %p %ld %p %ld)\n", iface, debugstr_w(pwzBaseUrl), debugstr_w(pwzRelativeUrl),
321 dwCombineFlags, pwzResult, cchResult, pcchResult, dwReserved);
325 static HRESULT WINAPI AboutProtocolInfo_CompareUrl(IInternetProtocolInfo *iface, LPCWSTR pwzUrl1,
326 LPCWSTR pwzUrl2, DWORD dwCompareFlags)
328 FIXME("%p)->(%s %s %08lx)\n", iface, debugstr_w(pwzUrl1), debugstr_w(pwzUrl2), dwCompareFlags);
332 static HRESULT WINAPI AboutProtocolInfo_QueryInfo(IInternetProtocolInfo *iface, LPCWSTR pwzUrl,
333 QUERYOPTION QueryOption, DWORD dwQueryFlags, LPVOID pBuffer, DWORD cbBuffer, DWORD* pcbBuf,
336 FIXME("%p)->(%s %08x %08lx %p %ld %p %ld)\n", iface, debugstr_w(pwzUrl), QueryOption, dwQueryFlags, pBuffer,
337 cbBuffer, pcbBuf, dwReserved);
341 static const IInternetProtocolInfoVtbl AboutProtocolInfoVtbl = {
342 InternetProtocolInfo_QueryInterface,
343 InternetProtocolInfo_AddRef,
344 InternetProtocolInfo_Release,
345 AboutProtocolInfo_ParseUrl,
346 AboutProtocolInfo_CombineUrl,
347 AboutProtocolInfo_CompareUrl,
348 AboutProtocolInfo_QueryInfo
351 static const IClassFactoryVtbl AboutProtocolFactoryVtbl = {
352 ClassFactory_QueryInterface,
354 ClassFactory_Release,
355 AboutProtocolFactory_CreateInstance,
356 ClassFactory_LockServer
359 static ProtocolFactory AboutProtocolFactory = {
360 &AboutProtocolInfoVtbl,
361 &AboutProtocolFactoryVtbl
364 /********************************************************************
365 * ResProtocol implementation
369 const IInternetProtocolVtbl *lpInternetProtocolVtbl;
377 static HRESULT WINAPI ResProtocol_QueryInterface(IInternetProtocol *iface, REFIID riid, void **ppv)
381 if(IsEqualGUID(&IID_IUnknown, riid)) {
382 TRACE("(%p)->(IID_IUnknown %p)\n", iface, ppv);
384 }else if(IsEqualGUID(&IID_IInternetProtocolRoot, riid)) {
385 TRACE("(%p)->(IID_IInternetProtocolRoot %p)\n", iface, ppv);
387 }else if(IsEqualGUID(&IID_IInternetProtocol, riid)) {
388 TRACE("(%p)->(IID_IInternetProtocol %p)\n", iface, ppv);
390 }else if(IsEqualGUID(&IID_IServiceProvider, riid)) {
391 FIXME("IServiceProvider is not implemented\n");
392 return E_NOINTERFACE;
396 TRACE("unknown interface %s\n", debugstr_guid(riid));
397 return E_NOINTERFACE;
400 IInternetProtocol_AddRef(iface);
404 static ULONG WINAPI ResProtocol_AddRef(IInternetProtocol *iface)
406 ResProtocol *This = (ResProtocol*)iface;
407 ULONG ref = InterlockedIncrement(&This->ref);
408 TRACE("(%p) ref=%ld\n", iface, ref);
412 static ULONG WINAPI ResProtocol_Release(IInternetProtocol *iface)
414 ResProtocol *This = (ResProtocol*)iface;
415 ULONG ref = InterlockedDecrement(&This->ref);
417 TRACE("(%p) ref=%lx\n", iface, ref);
420 HeapFree(GetProcessHeap(), 0, This->data);
421 HeapFree(GetProcessHeap(), 0, This);
428 static HRESULT WINAPI ResProtocol_Start(IInternetProtocol *iface, LPCWSTR szUrl,
429 IInternetProtocolSink* pOIProtSink, IInternetBindInfo* pOIBindInfo,
430 DWORD grfPI, DWORD dwReserved)
432 ResProtocol *This = (ResProtocol*)iface;
437 LPCWSTR url_dll, url_file;
441 static const WCHAR wszRes[] = {'r','e','s',':','/','/'};
443 TRACE("(%p)->(%s %p %p %08lx %ld)\n", This, debugstr_w(szUrl), pOIProtSink,
444 pOIBindInfo, grfPI, dwReserved);
446 memset(&bindinfo, 0, sizeof(bindinfo));
447 bindinfo.cbSize = sizeof(BINDINFO);
448 IInternetBindInfo_GetBindInfo(pOIBindInfo, &grfBINDF, &bindinfo);
451 * Implement MIME type checking
452 * Use CoInternetParseUrl (not implemented yet)
455 len = strlenW(szUrl);
456 if(len < sizeof(wszRes)/sizeof(wszRes[0]) || memcmp(szUrl, wszRes, sizeof(wszRes))) {
457 WARN("Wrong protocol of url: %s\n", debugstr_w(szUrl));
458 IInternetProtocolSink_ReportResult(pOIProtSink, MK_E_SYNTAX, 0, NULL);
462 url_dll = szUrl + sizeof(wszRes)/sizeof(wszRes[0]);
463 if(!(url_file = strchrW(url_dll, '/'))) {
464 WARN("wrong url: %s\n", debugstr_w(szUrl));
465 IInternetProtocolSink_ReportResult(pOIProtSink, MK_E_SYNTAX, 0, NULL);
469 memcpy(dll, url_dll, (url_file-url_dll)*sizeof(WCHAR));
470 dll[url_file-url_dll] = 0;
472 hdll = LoadLibraryExW(dll, NULL, LOAD_LIBRARY_AS_DATAFILE);
474 WARN("Could not open dll: %s\n", debugstr_w(dll));
475 IInternetProtocolSink_ReportResult(pOIProtSink, HRESULT_FROM_WIN32(GetLastError()), 0, NULL);
476 return HRESULT_FROM_WIN32(GetLastError());
479 src = FindResourceW(hdll, ++url_file, (LPCWSTR)RT_HTML);
481 WARN("Could not find resource: %s\n", debugstr_w(url_file));
482 IInternetProtocolSink_ReportResult(pOIProtSink, HRESULT_FROM_WIN32(GetLastError()), 0, NULL);
483 return HRESULT_FROM_WIN32(GetLastError());
487 WARN("data already loaded\n");
488 HeapFree(GetProcessHeap(), 0, This->data);
491 This->data_len = SizeofResource(hdll, src);
492 This->data = HeapAlloc(GetProcessHeap(), 0, This->data_len);
493 memcpy(This->data, LoadResource(hdll, src), This->data_len);
498 IInternetProtocolSink_ReportData(pOIProtSink,
499 BSCF_FIRSTDATANOTIFICATION | BSCF_LASTDATANOTIFICATION | BSCF_DATAFULLYAVAILABLE,
500 This->data_len, This->data_len);
502 IInternetProtocolSink_ReportResult(pOIProtSink, S_OK, 0, NULL);
507 static HRESULT WINAPI ResProtocol_Continue(IInternetProtocol *iface, PROTOCOLDATA* pProtocolData)
509 ResProtocol *This = (ResProtocol*)iface;
510 FIXME("(%p)->(%p)\n", This, pProtocolData);
514 static HRESULT WINAPI ResProtocol_Abort(IInternetProtocol *iface, HRESULT hrReason,
517 ResProtocol *This = (ResProtocol*)iface;
518 FIXME("(%p)->(%08lx %08lx)\n", This, hrReason, dwOptions);
522 static HRESULT WINAPI ResProtocol_Terminate(IInternetProtocol *iface, DWORD dwOptions)
524 ResProtocol *This = (ResProtocol*)iface;
526 TRACE("(%p)->(%08lx)\n", This, dwOptions);
528 /* test show that we don't have to do anything here */
532 static HRESULT WINAPI ResProtocol_Suspend(IInternetProtocol *iface)
534 ResProtocol *This = (ResProtocol*)iface;
535 FIXME("(%p)\n", This);
539 static HRESULT WINAPI ResProtocol_Resume(IInternetProtocol *iface)
541 ResProtocol *This = (ResProtocol*)iface;
542 FIXME("(%p)\n", This);
546 static HRESULT WINAPI ResProtocol_Read(IInternetProtocol *iface, void* pv, ULONG cb, ULONG* pcbRead)
548 ResProtocol *This = (ResProtocol*)iface;
550 TRACE("(%p)->(%p %lu %p)\n", This, pv, cb, pcbRead);
555 *pcbRead = (cb > This->data_len-This->cur ? This->data_len-This->cur : cb);
560 memcpy(pv, This->data, *pcbRead);
561 This->cur += *pcbRead;
566 static HRESULT WINAPI ResProtocol_Seek(IInternetProtocol *iface, LARGE_INTEGER dlibMove,
567 DWORD dwOrigin, ULARGE_INTEGER* plibNewPosition)
569 ResProtocol *This = (ResProtocol*)iface;
570 FIXME("(%p)->(%ld %ld %p)\n", This, dlibMove.u.LowPart, dwOrigin, plibNewPosition);
574 static HRESULT WINAPI ResProtocol_LockRequest(IInternetProtocol *iface, DWORD dwOptions)
576 ResProtocol *This = (ResProtocol*)iface;
578 TRACE("(%p)->(%ld)\n", This, dwOptions);
580 /* test show that we don't have to do anything here */
584 static HRESULT WINAPI ResProtocol_UnlockRequest(IInternetProtocol *iface)
586 ResProtocol *This = (ResProtocol*)iface;
588 TRACE("(%p)\n", This);
590 /* test show that we don't have to do anything here */
594 static const IInternetProtocolVtbl ResProtocolVtbl = {
595 ResProtocol_QueryInterface,
599 ResProtocol_Continue,
601 ResProtocol_Terminate,
606 ResProtocol_LockRequest,
607 ResProtocol_UnlockRequest
610 static HRESULT WINAPI ResProtocolFactory_CreateInstance(IClassFactory *iface, IUnknown *pUnkOuter,
611 REFIID riid, void **ppv)
616 TRACE("(%p)->(%s %p)\n", iface, debugstr_guid(riid), ppv);
618 ret = HeapAlloc(GetProcessHeap(), 0, sizeof(ResProtocol));
619 ret->lpInternetProtocolVtbl = &ResProtocolVtbl;
625 hres = IUnknown_QueryInterface((IUnknown*)ret, riid, ppv);
630 HeapFree(GetProcessHeap(), 0, ret);
635 static HRESULT WINAPI ResProtocolInfo_ParseUrl(IInternetProtocolInfo *iface, LPCWSTR pwzUrl,
636 PARSEACTION ParseAction, DWORD dwParseFlags, LPWSTR pwzResult, DWORD cchResult,
637 DWORD* pcchResult, DWORD dwReserved)
639 FIXME("%p)->(%s %08x %08lx %p %ld %p %ld)\n", iface, debugstr_w(pwzUrl), ParseAction,
640 dwParseFlags, pwzResult, cchResult, pcchResult, dwReserved);
644 static HRESULT WINAPI ResProtocolInfo_CombineUrl(IInternetProtocolInfo *iface, LPCWSTR pwzBaseUrl,
645 LPCWSTR pwzRelativeUrl, DWORD dwCombineFlags, LPWSTR pwzResult, DWORD cchResult,
646 DWORD* pcchResult, DWORD dwReserved)
648 FIXME("%p)->(%s %s %08lx %p %ld %p %ld)\n", iface, debugstr_w(pwzBaseUrl), debugstr_w(pwzRelativeUrl),
649 dwCombineFlags, pwzResult, cchResult, pcchResult, dwReserved);
653 static HRESULT WINAPI ResProtocolInfo_CompareUrl(IInternetProtocolInfo *iface, LPCWSTR pwzUrl1,
654 LPCWSTR pwzUrl2, DWORD dwCompareFlags)
656 FIXME("%p)->(%s %s %08lx)\n", iface, debugstr_w(pwzUrl1), debugstr_w(pwzUrl2), dwCompareFlags);
660 static HRESULT WINAPI ResProtocolInfo_QueryInfo(IInternetProtocolInfo *iface, LPCWSTR pwzUrl,
661 QUERYOPTION QueryOption, DWORD dwQueryFlags, LPVOID pBuffer, DWORD cbBuffer, DWORD* pcbBuf,
664 FIXME("%p)->(%s %08x %08lx %p %ld %p %ld)\n", iface, debugstr_w(pwzUrl), QueryOption, dwQueryFlags, pBuffer,
665 cbBuffer, pcbBuf, dwReserved);
669 static const IInternetProtocolInfoVtbl ResProtocolInfoVtbl = {
670 InternetProtocolInfo_QueryInterface,
671 InternetProtocolInfo_AddRef,
672 InternetProtocolInfo_Release,
673 ResProtocolInfo_ParseUrl,
674 ResProtocolInfo_CombineUrl,
675 ResProtocolInfo_CompareUrl,
676 ResProtocolInfo_QueryInfo
679 static const IClassFactoryVtbl ResProtocolFactoryVtbl = {
680 ClassFactory_QueryInterface,
682 ClassFactory_Release,
683 ResProtocolFactory_CreateInstance,
684 ClassFactory_LockServer
687 static ProtocolFactory ResProtocolFactory = {
688 &ResProtocolInfoVtbl,
689 &ResProtocolFactoryVtbl
692 HRESULT ProtocolFactory_Create(REFCLSID rclsid, REFIID riid, void **ppv)
694 ProtocolFactory *cf = NULL;
696 if(IsEqualGUID(&CLSID_AboutProtocol, rclsid))
697 cf = &AboutProtocolFactory;
698 else if(IsEqualGUID(&CLSID_ResProtocol, rclsid))
699 cf = &ResProtocolFactory;
702 FIXME("not implemented protocol %s\n", debugstr_guid(rclsid));
703 return CLASS_E_CLASSNOTAVAILABLE;
706 return IUnknown_QueryInterface((IUnknown*)cf, riid, ppv);