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
34 #include "wine/debug.h"
35 #include "wine/unicode.h"
37 #include "mshtml_private.h"
39 WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
41 /********************************************************************
42 * common ProtocolFactory implementation
45 #define PROTOCOLINFO(x) ((IInternetProtocolInfo*) &(x)->lpInternetProtocolInfoVtbl)
46 #define CLASSFACTORY(x) ((IClassFactory*) &(x)->lpClassFactoryVtbl)
49 const IInternetProtocolInfoVtbl *lpInternetProtocolInfoVtbl;
50 const IClassFactoryVtbl *lpClassFactoryVtbl;
53 #define PROTOCOLINFO_THIS(iface) \
54 (ProtocolFactory*)((char*)(iface)-offsetof(ProtocolFactory,lpInternetProtocolInfoVtbl))
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);
88 static ULONG WINAPI InternetProtocolInfo_Release(IInternetProtocolInfo *iface)
90 ProtocolFactory *This = PROTOCOLINFO_THIS(iface);
91 TRACE("(%p)\n", This);
95 #undef PROTOCOLINFO_THIS
97 #define CLASSFACTORY_THIS(iface) \
98 (ProtocolFactory*)((char*)(iface)-offsetof(ProtocolFactory,lpClassFactoryVtbl))
100 static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv)
102 ProtocolFactory *This = CLASSFACTORY_THIS(iface);
103 return IInternetProtocolInfo_QueryInterface(PROTOCOLINFO(This), riid, ppv);
106 static ULONG WINAPI ClassFactory_AddRef(IClassFactory *iface)
108 ProtocolFactory *This = CLASSFACTORY_THIS(iface);
109 return IInternetProtocolInfo_AddRef(PROTOCOLINFO(This));
112 static ULONG WINAPI ClassFactory_Release(IClassFactory *iface)
114 ProtocolFactory *This = CLASSFACTORY_THIS(iface);
115 return IInternetProtocolInfo_Release(PROTOCOLINFO(This));
118 static HRESULT WINAPI ClassFactory_LockServer(IClassFactory *iface, BOOL dolock)
120 ProtocolFactory *This = CLASSFACTORY_THIS(iface);
121 FIXME("(%p)->(%x)\n", This, dolock);
125 #undef CLASSFACTORY_THIS
127 /********************************************************************
128 * AboutProtocol implementation
132 const IInternetProtocolVtbl *lpInternetProtocolVtbl;
136 static HRESULT WINAPI AboutProtocol_QueryInterface(IInternetProtocol *iface, REFIID riid, void **ppv)
140 if(IsEqualGUID(&IID_IUnknown, riid)) {
141 TRACE("(%p)->(IID_IUnknown %p)\n", iface, ppv);
143 }else if(IsEqualGUID(&IID_IInternetProtocolRoot, riid)) {
144 TRACE("(%p)->(IID_IInternetProtocolRoot %p)\n", iface, ppv);
146 }else if(IsEqualGUID(&IID_IInternetProtocol, riid)) {
147 TRACE("(%p)->(IID_IInternetProtocol %p)\n", iface, ppv);
149 }else if(IsEqualGUID(&IID_IServiceProvider, riid)) {
150 FIXME("IServiceProvider is not implemented\n");
151 return E_NOINTERFACE;
155 TRACE("unknown interface %s\n", debugstr_guid(riid));
156 return E_NOINTERFACE;
159 IInternetProtocol_AddRef(iface);
163 static ULONG WINAPI AboutProtocol_AddRef(IInternetProtocol *iface)
165 AboutProtocol *This = (AboutProtocol*)iface;
166 ULONG ref = InterlockedIncrement(&This->ref);
167 TRACE("(%p) ref=%ld\n", iface, ref);
171 static ULONG WINAPI AboutProtocol_Release(IInternetProtocol *iface)
173 AboutProtocol *This = (AboutProtocol*)iface;
174 ULONG ref = InterlockedDecrement(&This->ref);
176 TRACE("(%p) ref=%lx\n", iface, ref);
179 HeapFree(GetProcessHeap(), 0, This);
184 static HRESULT WINAPI AboutProtocol_Start(IInternetProtocol *iface, LPCWSTR szUrl,
185 IInternetProtocolSink* pOIProtSink, IInternetBindInfo* pOIBindInfo,
186 DWORD grfPI, DWORD dwReserved)
188 AboutProtocol *This = (AboutProtocol*)iface;
189 FIXME("(%p)->(%s %p %p %08lx %ld)\n", This, debugstr_w(szUrl), pOIProtSink,
190 pOIBindInfo, grfPI, dwReserved);
194 static HRESULT WINAPI AboutProtocol_Continue(IInternetProtocol *iface, PROTOCOLDATA* pProtocolData)
196 AboutProtocol *This = (AboutProtocol*)iface;
197 FIXME("(%p)->(%p)\n", This, pProtocolData);
201 static HRESULT WINAPI AboutProtocol_Abort(IInternetProtocol *iface, HRESULT hrReason,
204 AboutProtocol *This = (AboutProtocol*)iface;
205 FIXME("(%p)->(%08lx %08lx)\n", This, hrReason, dwOptions);
209 static HRESULT WINAPI AboutProtocol_Terminate(IInternetProtocol *iface, DWORD dwOptions)
211 AboutProtocol *This = (AboutProtocol*)iface;
212 FIXME("(%p)->(%08lx)\n", This, dwOptions);
216 static HRESULT WINAPI AboutProtocol_Suspend(IInternetProtocol *iface)
218 AboutProtocol *This = (AboutProtocol*)iface;
219 FIXME("(%p)\n", This);
223 static HRESULT WINAPI AboutProtocol_Resume(IInternetProtocol *iface)
225 AboutProtocol *This = (AboutProtocol*)iface;
226 FIXME("(%p)\n", This);
230 static HRESULT WINAPI AboutProtocol_Read(IInternetProtocol *iface, void* pv, ULONG cb, ULONG* pcbRead)
232 AboutProtocol *This = (AboutProtocol*)iface;
233 FIXME("(%p)->(%lu %p)\n", This, cb, pcbRead);
237 static HRESULT WINAPI AboutProtocol_Seek(IInternetProtocol *iface, LARGE_INTEGER dlibMove,
238 DWORD dwOrigin, ULARGE_INTEGER* plibNewPosition)
240 AboutProtocol *This = (AboutProtocol*)iface;
241 FIXME("(%p)->(%ld %ld %p)\n", This, dlibMove.u.LowPart, dwOrigin, plibNewPosition);
245 static HRESULT WINAPI AboutProtocol_LockRequest(IInternetProtocol *iface, DWORD dwOptions)
247 AboutProtocol *This = (AboutProtocol*)iface;
248 FIXME("(%p)->(%ld)\n", This, dwOptions);
252 static HRESULT WINAPI AboutProtocol_UnlockRequest(IInternetProtocol *iface)
254 AboutProtocol *This = (AboutProtocol*)iface;
255 FIXME("(%p)\n", This);
259 static const IInternetProtocolVtbl AboutProtocolVtbl = {
260 AboutProtocol_QueryInterface,
261 AboutProtocol_AddRef,
262 AboutProtocol_Release,
264 AboutProtocol_Continue,
266 AboutProtocol_Terminate,
267 AboutProtocol_Suspend,
268 AboutProtocol_Resume,
271 AboutProtocol_LockRequest,
272 AboutProtocol_UnlockRequest
275 static HRESULT WINAPI AboutProtocolFactory_CreateInstance(IClassFactory *iface, IUnknown *pUnkOuter,
276 REFIID riid, void **ppv)
281 TRACE("(%p)->(%s %p)\n", iface, debugstr_guid(riid), ppv);
283 ret = HeapAlloc(GetProcessHeap(), 0, sizeof(AboutProtocol));
284 ret->lpInternetProtocolVtbl = &AboutProtocolVtbl;
287 hres = IUnknown_QueryInterface((IUnknown*)ret, riid, ppv);
290 HeapFree(GetProcessHeap(), 0, ret);
295 static HRESULT WINAPI AboutProtocolInfo_ParseUrl(IInternetProtocolInfo *iface, LPCWSTR pwzUrl,
296 PARSEACTION ParseAction, DWORD dwParseFlags, LPWSTR pwzResult, DWORD cchResult,
297 DWORD* pcchResult, DWORD dwReserved)
299 FIXME("%p)->(%s %08x %08lx %p %ld %p %ld)\n", iface, debugstr_w(pwzUrl), ParseAction,
300 dwParseFlags, pwzResult, cchResult, pcchResult, dwReserved);
304 static HRESULT WINAPI AboutProtocolInfo_CombineUrl(IInternetProtocolInfo *iface, LPCWSTR pwzBaseUrl,
305 LPCWSTR pwzRelativeUrl, DWORD dwCombineFlags, LPWSTR pwzResult, DWORD cchResult,
306 DWORD* pcchResult, DWORD dwReserved)
308 FIXME("%p)->(%s %s %08lx %p %ld %p %ld)\n", iface, debugstr_w(pwzBaseUrl), debugstr_w(pwzRelativeUrl),
309 dwCombineFlags, pwzResult, cchResult, pcchResult, dwReserved);
313 static HRESULT WINAPI AboutProtocolInfo_CompareUrl(IInternetProtocolInfo *iface, LPCWSTR pwzUrl1,
314 LPCWSTR pwzUrl2, DWORD dwCompareFlags)
316 FIXME("%p)->(%s %s %08lx)\n", iface, debugstr_w(pwzUrl1), debugstr_w(pwzUrl2), dwCompareFlags);
320 static HRESULT WINAPI AboutProtocolInfo_QueryInfo(IInternetProtocolInfo *iface, LPCWSTR pwzUrl,
321 QUERYOPTION QueryOption, DWORD dwQueryFlags, LPVOID pBuffer, DWORD cbBuffer, DWORD* pcbBuf,
324 FIXME("%p)->(%s %08x %08lx %p %ld %p %ld)\n", iface, debugstr_w(pwzUrl), QueryOption, dwQueryFlags, pBuffer,
325 cbBuffer, pcbBuf, dwReserved);
329 static const IInternetProtocolInfoVtbl AboutProtocolInfoVtbl = {
330 InternetProtocolInfo_QueryInterface,
331 InternetProtocolInfo_AddRef,
332 InternetProtocolInfo_Release,
333 AboutProtocolInfo_ParseUrl,
334 AboutProtocolInfo_CombineUrl,
335 AboutProtocolInfo_CompareUrl,
336 AboutProtocolInfo_QueryInfo
339 static const IClassFactoryVtbl AboutProtocolFactoryVtbl = {
340 ClassFactory_QueryInterface,
342 ClassFactory_Release,
343 AboutProtocolFactory_CreateInstance,
344 ClassFactory_LockServer
347 static ProtocolFactory AboutProtocolFactory = {
348 &AboutProtocolInfoVtbl,
349 &AboutProtocolFactoryVtbl
352 /********************************************************************
353 * ResProtocol implementation
357 const IInternetProtocolVtbl *lpInternetProtocolVtbl;
365 static HRESULT WINAPI ResProtocol_QueryInterface(IInternetProtocol *iface, REFIID riid, void **ppv)
369 if(IsEqualGUID(&IID_IUnknown, riid)) {
370 TRACE("(%p)->(IID_IUnknown %p)\n", iface, ppv);
372 }else if(IsEqualGUID(&IID_IInternetProtocolRoot, riid)) {
373 TRACE("(%p)->(IID_IInternetProtocolRoot %p)\n", iface, ppv);
375 }else if(IsEqualGUID(&IID_IInternetProtocol, riid)) {
376 TRACE("(%p)->(IID_IInternetProtocol %p)\n", iface, ppv);
378 }else if(IsEqualGUID(&IID_IServiceProvider, riid)) {
379 FIXME("IServiceProvider is not implemented\n");
380 return E_NOINTERFACE;
384 TRACE("unknown interface %s\n", debugstr_guid(riid));
385 return E_NOINTERFACE;
388 IInternetProtocol_AddRef(iface);
392 static ULONG WINAPI ResProtocol_AddRef(IInternetProtocol *iface)
394 ResProtocol *This = (ResProtocol*)iface;
395 ULONG ref = InterlockedIncrement(&This->ref);
396 TRACE("(%p) ref=%ld\n", iface, ref);
400 static ULONG WINAPI ResProtocol_Release(IInternetProtocol *iface)
402 ResProtocol *This = (ResProtocol*)iface;
403 ULONG ref = InterlockedDecrement(&This->ref);
405 TRACE("(%p) ref=%lx\n", iface, ref);
408 HeapFree(GetProcessHeap(), 0, This->data);
409 HeapFree(GetProcessHeap(), 0, This);
415 static HRESULT WINAPI ResProtocol_Start(IInternetProtocol *iface, LPCWSTR szUrl,
416 IInternetProtocolSink* pOIProtSink, IInternetBindInfo* pOIBindInfo,
417 DWORD grfPI, DWORD dwReserved)
419 ResProtocol *This = (ResProtocol*)iface;
424 LPCWSTR url_dll, url_file;
428 static const WCHAR wszRes[] = {'r','e','s',':','/','/'};
430 TRACE("(%p)->(%s %p %p %08lx %ld)\n", This, debugstr_w(szUrl), pOIProtSink,
431 pOIBindInfo, grfPI, dwReserved);
433 memset(&bindinfo, 0, sizeof(bindinfo));
434 bindinfo.cbSize = sizeof(BINDINFO);
435 IInternetBindInfo_GetBindInfo(pOIBindInfo, &grfBINDF, &bindinfo);
438 * Implement MIME type checking
439 * Use CoInternetParseUrl (not implemented yet)
442 len = strlenW(szUrl);
443 if(len < sizeof(wszRes)/sizeof(wszRes[0]) || memcmp(szUrl, wszRes, sizeof(wszRes))) {
444 WARN("Wrong protocol of url: %s\n", debugstr_w(szUrl));
445 IInternetProtocolSink_ReportResult(pOIProtSink, MK_E_SYNTAX, 0, NULL);
449 url_dll = szUrl + sizeof(wszRes)/sizeof(wszRes[0]);
450 if(!(url_file = strchrW(url_dll, '/'))) {
451 WARN("wrong url: %s\n", debugstr_w(szUrl));
452 IInternetProtocolSink_ReportResult(pOIProtSink, MK_E_SYNTAX, 0, NULL);
456 memcpy(dll, url_dll, (url_file-url_dll)*sizeof(WCHAR));
457 dll[url_file-url_dll] = 0;
459 hdll = LoadLibraryExW(dll, NULL, LOAD_LIBRARY_AS_DATAFILE);
461 WARN("Could not open dll: %s\n", debugstr_w(dll));
462 IInternetProtocolSink_ReportResult(pOIProtSink, HRESULT_FROM_WIN32(GetLastError()), 0, NULL);
463 return HRESULT_FROM_WIN32(GetLastError());
466 src = FindResourceW(hdll, ++url_file, (LPCWSTR)RT_HTML);
468 WARN("Could not find resource: %s\n", debugstr_w(url_file));
469 IInternetProtocolSink_ReportResult(pOIProtSink, HRESULT_FROM_WIN32(GetLastError()), 0, NULL);
470 return HRESULT_FROM_WIN32(GetLastError());
474 WARN("data already loaded\n");
475 HeapFree(GetProcessHeap(), 0, This->data);
478 This->data_len = SizeofResource(hdll, src);
479 This->data = HeapAlloc(GetProcessHeap(), 0, This->data_len);
480 memcpy(This->data, LoadResource(hdll, src), This->data_len);
485 IInternetProtocolSink_ReportData(pOIProtSink,
486 BSCF_FIRSTDATANOTIFICATION | BSCF_LASTDATANOTIFICATION | BSCF_DATAFULLYAVAILABLE,
487 This->data_len, This->data_len);
489 IInternetProtocolSink_ReportResult(pOIProtSink, S_OK, 0, NULL);
494 static HRESULT WINAPI ResProtocol_Continue(IInternetProtocol *iface, PROTOCOLDATA* pProtocolData)
496 ResProtocol *This = (ResProtocol*)iface;
497 FIXME("(%p)->(%p)\n", This, pProtocolData);
501 static HRESULT WINAPI ResProtocol_Abort(IInternetProtocol *iface, HRESULT hrReason,
504 ResProtocol *This = (ResProtocol*)iface;
505 FIXME("(%p)->(%08lx %08lx)\n", This, hrReason, dwOptions);
509 static HRESULT WINAPI ResProtocol_Terminate(IInternetProtocol *iface, DWORD dwOptions)
511 ResProtocol *This = (ResProtocol*)iface;
513 TRACE("(%p)->(%08lx)\n", This, dwOptions);
515 /* test show that we don't have to do anything here */
519 static HRESULT WINAPI ResProtocol_Suspend(IInternetProtocol *iface)
521 ResProtocol *This = (ResProtocol*)iface;
522 FIXME("(%p)\n", This);
526 static HRESULT WINAPI ResProtocol_Resume(IInternetProtocol *iface)
528 ResProtocol *This = (ResProtocol*)iface;
529 FIXME("(%p)\n", This);
533 static HRESULT WINAPI ResProtocol_Read(IInternetProtocol *iface, void* pv, ULONG cb, ULONG* pcbRead)
535 ResProtocol *This = (ResProtocol*)iface;
537 TRACE("(%p)->(%p %lu %p)\n", This, pv, cb, pcbRead);
542 *pcbRead = (cb > This->data_len-This->cur ? This->data_len-This->cur : cb);
547 memcpy(pv, This->data, *pcbRead);
548 This->cur += *pcbRead;
553 static HRESULT WINAPI ResProtocol_Seek(IInternetProtocol *iface, LARGE_INTEGER dlibMove,
554 DWORD dwOrigin, ULARGE_INTEGER* plibNewPosition)
556 ResProtocol *This = (ResProtocol*)iface;
557 FIXME("(%p)->(%ld %ld %p)\n", This, dlibMove.u.LowPart, dwOrigin, plibNewPosition);
561 static HRESULT WINAPI ResProtocol_LockRequest(IInternetProtocol *iface, DWORD dwOptions)
563 ResProtocol *This = (ResProtocol*)iface;
565 TRACE("(%p)->(%ld)\n", This, dwOptions);
567 /* test show that we don't have to do anything here */
571 static HRESULT WINAPI ResProtocol_UnlockRequest(IInternetProtocol *iface)
573 ResProtocol *This = (ResProtocol*)iface;
575 TRACE("(%p)\n", This);
577 /* test show that we don't have to do anything here */
581 static const IInternetProtocolVtbl ResProtocolVtbl = {
582 ResProtocol_QueryInterface,
586 ResProtocol_Continue,
588 ResProtocol_Terminate,
593 ResProtocol_LockRequest,
594 ResProtocol_UnlockRequest
597 static HRESULT WINAPI ResProtocolFactory_CreateInstance(IClassFactory *iface, IUnknown *pUnkOuter,
598 REFIID riid, void **ppv)
603 TRACE("(%p)->(%s %p)\n", iface, debugstr_guid(riid), ppv);
605 ret = HeapAlloc(GetProcessHeap(), 0, sizeof(ResProtocol));
606 ret->lpInternetProtocolVtbl = &ResProtocolVtbl;
612 hres = IUnknown_QueryInterface((IUnknown*)ret, riid, ppv);
615 HeapFree(GetProcessHeap(), 0, ret);
620 static HRESULT WINAPI ResProtocolInfo_ParseUrl(IInternetProtocolInfo *iface, LPCWSTR pwzUrl,
621 PARSEACTION ParseAction, DWORD dwParseFlags, LPWSTR pwzResult, DWORD cchResult,
622 DWORD* pcchResult, DWORD dwReserved)
624 FIXME("%p)->(%s %08x %08lx %p %ld %p %ld)\n", iface, debugstr_w(pwzUrl), ParseAction,
625 dwParseFlags, pwzResult, cchResult, pcchResult, dwReserved);
629 static HRESULT WINAPI ResProtocolInfo_CombineUrl(IInternetProtocolInfo *iface, LPCWSTR pwzBaseUrl,
630 LPCWSTR pwzRelativeUrl, DWORD dwCombineFlags, LPWSTR pwzResult, DWORD cchResult,
631 DWORD* pcchResult, DWORD dwReserved)
633 FIXME("%p)->(%s %s %08lx %p %ld %p %ld)\n", iface, debugstr_w(pwzBaseUrl), debugstr_w(pwzRelativeUrl),
634 dwCombineFlags, pwzResult, cchResult, pcchResult, dwReserved);
638 static HRESULT WINAPI ResProtocolInfo_CompareUrl(IInternetProtocolInfo *iface, LPCWSTR pwzUrl1,
639 LPCWSTR pwzUrl2, DWORD dwCompareFlags)
641 FIXME("%p)->(%s %s %08lx)\n", iface, debugstr_w(pwzUrl1), debugstr_w(pwzUrl2), dwCompareFlags);
645 static HRESULT WINAPI ResProtocolInfo_QueryInfo(IInternetProtocolInfo *iface, LPCWSTR pwzUrl,
646 QUERYOPTION QueryOption, DWORD dwQueryFlags, LPVOID pBuffer, DWORD cbBuffer, DWORD* pcbBuf,
649 FIXME("%p)->(%s %08x %08lx %p %ld %p %ld)\n", iface, debugstr_w(pwzUrl), QueryOption, dwQueryFlags, pBuffer,
650 cbBuffer, pcbBuf, dwReserved);
654 static const IInternetProtocolInfoVtbl ResProtocolInfoVtbl = {
655 InternetProtocolInfo_QueryInterface,
656 InternetProtocolInfo_AddRef,
657 InternetProtocolInfo_Release,
658 ResProtocolInfo_ParseUrl,
659 ResProtocolInfo_CombineUrl,
660 ResProtocolInfo_CompareUrl,
661 ResProtocolInfo_QueryInfo
664 static const IClassFactoryVtbl ResProtocolFactoryVtbl = {
665 ClassFactory_QueryInterface,
667 ClassFactory_Release,
668 ResProtocolFactory_CreateInstance,
669 ClassFactory_LockServer
672 static ProtocolFactory ResProtocolFactory = {
673 &ResProtocolInfoVtbl,
674 &ResProtocolFactoryVtbl
677 HRESULT ProtocolFactory_Create(REFCLSID rclsid, REFIID riid, void **ppv)
679 ProtocolFactory *cf = NULL;
681 if(IsEqualGUID(&CLSID_AboutProtocol, rclsid))
682 cf = &AboutProtocolFactory;
683 else if(IsEqualGUID(&CLSID_ResProtocol, rclsid))
684 cf = &ResProtocolFactory;
687 FIXME("not implemented protocol %s\n", debugstr_guid(rclsid));
688 return CLASS_E_CLASSNOTAVAILABLE;
691 return IUnknown_QueryInterface((IUnknown*)cf, riid, ppv);