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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 #define WIN32_NO_STATUS
21 #define COM_NO_WINDOWS_H
32 //#include "winuser.h"
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 CLASSFACTORY(x) (&(x)->lpClassFactoryVtbl)
47 #define PROTOCOL(x) ((IInternetProtocol*) &(x)->lpInternetProtocolVtbl)
48 #define PROTOCOLINFO(x) ((IInternetProtocolInfo*) &(x)->lpInternetProtocolInfoVtbl)
51 const IInternetProtocolInfoVtbl
*lpInternetProtocolInfoVtbl
;
52 const IClassFactoryVtbl
*lpClassFactoryVtbl
;
55 #define PROTOCOLINFO_THIS(iface) DEFINE_THIS(ProtocolFactory, InternetProtocolInfo, iface)
57 static HRESULT WINAPI
InternetProtocolInfo_QueryInterface(IInternetProtocolInfo
*iface
, REFIID riid
, void **ppv
)
59 ProtocolFactory
*This
= PROTOCOLINFO_THIS(iface
);
62 if(IsEqualGUID(&IID_IUnknown
, riid
)) {
63 TRACE("(%p)->(IID_IUnknown %p)\n", This
, ppv
);
64 *ppv
= PROTOCOLINFO(This
);
65 }else if(IsEqualGUID(&IID_IInternetProtocolInfo
, riid
)) {
66 TRACE("(%p)->(IID_IInternetProtocolInfo %p)\n", This
, ppv
);
67 *ppv
= PROTOCOLINFO(This
);
68 }else if(IsEqualGUID(&IID_IClassFactory
, riid
)) {
69 TRACE("(%p)->(IID_IClassFactory %p)\n", This
, ppv
);
70 *ppv
= CLASSFACTORY(This
);
74 WARN("unknown interface %s\n", debugstr_guid(riid
));
78 IInternetProtocolInfo_AddRef(iface
);
82 static ULONG WINAPI
InternetProtocolInfo_AddRef(IInternetProtocolInfo
*iface
)
84 TRACE("(%p)\n", iface
);
88 static ULONG WINAPI
InternetProtocolInfo_Release(IInternetProtocolInfo
*iface
)
90 TRACE("(%p)\n", iface
);
94 static HRESULT WINAPI
InternetProtocolInfo_CombineUrl(IInternetProtocolInfo
*iface
,
95 LPCWSTR pwzBaseUrl
, LPCWSTR pwzRelativeUrl
, DWORD dwCombineFlags
, LPWSTR pwzResult
,
96 DWORD cchResult
, DWORD
* pcchResult
, DWORD dwReserved
)
98 TRACE("%p)->(%s %s %08x %p %d %p %d)\n", iface
, debugstr_w(pwzBaseUrl
),
99 debugstr_w(pwzRelativeUrl
), dwCombineFlags
, pwzResult
, cchResult
,
100 pcchResult
, dwReserved
);
102 return INET_E_USE_DEFAULT_PROTOCOLHANDLER
;
105 static HRESULT WINAPI
InternetProtocolInfo_CompareUrl(IInternetProtocolInfo
*iface
, LPCWSTR pwzUrl1
,
106 LPCWSTR pwzUrl2
, DWORD dwCompareFlags
)
108 TRACE("%p)->(%s %s %08x)\n", iface
, debugstr_w(pwzUrl1
), debugstr_w(pwzUrl2
), dwCompareFlags
);
112 #undef PROTOCOLINFO_THIS
114 #define CLASSFACTORY_THIS(iface) DEFINE_THIS(ProtocolFactory, ClassFactory, iface)
116 static HRESULT WINAPI
ClassFactory_QueryInterface(IClassFactory
*iface
, REFIID riid
, void **ppv
)
118 ProtocolFactory
*This
= CLASSFACTORY_THIS(iface
);
119 return IInternetProtocolInfo_QueryInterface(PROTOCOLINFO(This
), riid
, ppv
);
122 static ULONG WINAPI
ClassFactory_AddRef(IClassFactory
*iface
)
124 ProtocolFactory
*This
= CLASSFACTORY_THIS(iface
);
125 return IInternetProtocolInfo_AddRef(PROTOCOLINFO(This
));
128 static ULONG WINAPI
ClassFactory_Release(IClassFactory
*iface
)
130 ProtocolFactory
*This
= CLASSFACTORY_THIS(iface
);
131 return IInternetProtocolInfo_Release(PROTOCOLINFO(This
));
134 static HRESULT WINAPI
ClassFactory_LockServer(IClassFactory
*iface
, BOOL dolock
)
136 TRACE("(%p)->(%x)\n", iface
, dolock
);
140 #undef CLASSFACTORY_THIS
142 /********************************************************************
143 * AboutProtocol implementation
147 const IInternetProtocolVtbl
*lpInternetProtocolVtbl
;
158 #define PROTOCOL_THIS(iface) DEFINE_THIS(AboutProtocol, InternetProtocol, iface)
160 static HRESULT WINAPI
AboutProtocol_QueryInterface(IInternetProtocol
*iface
, REFIID riid
, void **ppv
)
162 AboutProtocol
*This
= PROTOCOL_THIS(iface
);
166 if(IsEqualGUID(&IID_IUnknown
, riid
)) {
167 TRACE("(%p)->(IID_IUnknown %p)\n", iface
, ppv
);
169 return IUnknown_QueryInterface(This
->pUnkOuter
, riid
, ppv
);
170 *ppv
= PROTOCOL(This
);
171 }else if(IsEqualGUID(&IID_IInternetProtocolRoot
, riid
)) {
172 TRACE("(%p)->(IID_IInternetProtocolRoot %p)\n", iface
, ppv
);
173 *ppv
= PROTOCOL(This
);
174 }else if(IsEqualGUID(&IID_IInternetProtocol
, riid
)) {
175 TRACE("(%p)->(IID_IInternetProtocol %p)\n", iface
, ppv
);
176 *ppv
= PROTOCOL(This
);
177 }else if(IsEqualGUID(&IID_IServiceProvider
, riid
)) {
178 FIXME("IServiceProvider is not implemented\n");
179 return E_NOINTERFACE
;
183 TRACE("unknown interface %s\n", debugstr_guid(riid
));
184 return E_NOINTERFACE
;
187 IInternetProtocol_AddRef(iface
);
191 static ULONG WINAPI
AboutProtocol_AddRef(IInternetProtocol
*iface
)
193 AboutProtocol
*This
= PROTOCOL_THIS(iface
);
194 ULONG ref
= InterlockedIncrement(&This
->ref
);
195 TRACE("(%p) ref=%d\n", iface
, ref
);
196 return This
->pUnkOuter
? IUnknown_AddRef(This
->pUnkOuter
) : ref
;
199 static ULONG WINAPI
AboutProtocol_Release(IInternetProtocol
*iface
)
201 AboutProtocol
*This
= PROTOCOL_THIS(iface
);
202 IUnknown
*pUnkOuter
= This
->pUnkOuter
;
203 ULONG ref
= InterlockedDecrement(&This
->ref
);
205 TRACE("(%p) ref=%x\n", iface
, ref
);
208 heap_free(This
->data
);
212 return pUnkOuter
? IUnknown_Release(pUnkOuter
) : ref
;
215 static HRESULT WINAPI
AboutProtocol_Start(IInternetProtocol
*iface
, LPCWSTR szUrl
,
216 IInternetProtocolSink
* pOIProtSink
, IInternetBindInfo
* pOIBindInfo
,
217 DWORD grfPI
, HANDLE_PTR dwReserved
)
219 AboutProtocol
*This
= PROTOCOL_THIS(iface
);
224 static const WCHAR html_begin
[] = {0xfeff,'<','H','T','M','L','>',0};
225 static const WCHAR html_end
[] = {'<','/','H','T','M','L','>',0};
226 static const WCHAR wszBlank
[] = {'b','l','a','n','k',0};
227 static const WCHAR wszAbout
[] = {'a','b','o','u','t',':'};
228 static const WCHAR wszTextHtml
[] = {'t','e','x','t','/','h','t','m','l',0};
231 * the about protocol seems not to work as I would expect. It creates html document
232 * for a given url, eg. about:some_text -> <HTML>some_text</HTML> except for the case when
233 * some_text = "blank", when document is blank (<HTML></HMTL>). The same happens
234 * when the url does not have "about:" in the beginning.
237 TRACE("(%p)->(%s %p %p %08x %lx)\n", This
, debugstr_w(szUrl
), pOIProtSink
,
238 pOIBindInfo
, grfPI
, dwReserved
);
240 memset(&bindinfo
, 0, sizeof(bindinfo
));
241 bindinfo
.cbSize
= sizeof(BINDINFO
);
242 IInternetBindInfo_GetBindInfo(pOIBindInfo
, &grfBINDF
, &bindinfo
);
243 ReleaseBindInfo(&bindinfo
);
245 TRACE("bindf %x\n", grfBINDF
);
247 if(strlenW(szUrl
)>=sizeof(wszAbout
)/sizeof(WCHAR
) && !memcmp(wszAbout
, szUrl
, sizeof(wszAbout
))) {
248 text
= szUrl
+ sizeof(wszAbout
)/sizeof(WCHAR
);
249 if(!strcmpW(wszBlank
, text
))
253 This
->data_len
= sizeof(html_begin
)+sizeof(html_end
)-sizeof(WCHAR
)
254 + (text
? strlenW(text
)*sizeof(WCHAR
) : 0);
255 This
->data
= heap_alloc(This
->data_len
);
257 memcpy(This
->data
, html_begin
, sizeof(html_begin
));
259 strcatW((LPWSTR
)This
->data
, text
);
260 strcatW((LPWSTR
)This
->data
, html_end
);
264 IInternetProtocolSink_ReportProgress(pOIProtSink
, BINDSTATUS_MIMETYPEAVAILABLE
, wszTextHtml
);
266 IInternetProtocolSink_ReportData(pOIProtSink
,
267 BSCF_FIRSTDATANOTIFICATION
| BSCF_LASTDATANOTIFICATION
| BSCF_DATAFULLYAVAILABLE
,
268 This
->data_len
, This
->data_len
);
270 IInternetProtocolSink_ReportResult(pOIProtSink
, S_OK
, 0, NULL
);
275 static HRESULT WINAPI
AboutProtocol_Continue(IInternetProtocol
*iface
, PROTOCOLDATA
* pProtocolData
)
277 AboutProtocol
*This
= PROTOCOL_THIS(iface
);
278 FIXME("(%p)->(%p)\n", This
, pProtocolData
);
282 static HRESULT WINAPI
AboutProtocol_Abort(IInternetProtocol
*iface
, HRESULT hrReason
,
285 AboutProtocol
*This
= PROTOCOL_THIS(iface
);
286 FIXME("(%p)->(%08x %08x)\n", This
, hrReason
, dwOptions
);
290 static HRESULT WINAPI
AboutProtocol_Terminate(IInternetProtocol
*iface
, DWORD dwOptions
)
292 AboutProtocol
*This
= PROTOCOL_THIS(iface
);
293 TRACE("(%p)->(%08x)\n", This
, dwOptions
);
297 static HRESULT WINAPI
AboutProtocol_Suspend(IInternetProtocol
*iface
)
299 AboutProtocol
*This
= PROTOCOL_THIS(iface
);
300 FIXME("(%p)\n", This
);
304 static HRESULT WINAPI
AboutProtocol_Resume(IInternetProtocol
*iface
)
306 AboutProtocol
*This
= PROTOCOL_THIS(iface
);
307 FIXME("(%p)\n", This
);
311 static HRESULT WINAPI
AboutProtocol_Read(IInternetProtocol
*iface
, void* pv
, ULONG cb
, ULONG
* pcbRead
)
313 AboutProtocol
*This
= PROTOCOL_THIS(iface
);
315 TRACE("(%p)->(%p %u %p)\n", This
, pv
, cb
, pcbRead
);
320 *pcbRead
= (cb
> This
->data_len
-This
->cur
? This
->data_len
-This
->cur
: cb
);
325 memcpy(pv
, This
->data
+This
->cur
, *pcbRead
);
326 This
->cur
+= *pcbRead
;
331 static HRESULT WINAPI
AboutProtocol_Seek(IInternetProtocol
*iface
, LARGE_INTEGER dlibMove
,
332 DWORD dwOrigin
, ULARGE_INTEGER
* plibNewPosition
)
334 AboutProtocol
*This
= PROTOCOL_THIS(iface
);
335 FIXME("(%p)->(%d %d %p)\n", This
, dlibMove
.u
.LowPart
, dwOrigin
, plibNewPosition
);
339 static HRESULT WINAPI
AboutProtocol_LockRequest(IInternetProtocol
*iface
, DWORD dwOptions
)
341 AboutProtocol
*This
= PROTOCOL_THIS(iface
);
343 TRACE("(%p)->(%d)\n", This
, dwOptions
);
348 static HRESULT WINAPI
AboutProtocol_UnlockRequest(IInternetProtocol
*iface
)
350 AboutProtocol
*This
= PROTOCOL_THIS(iface
);
352 TRACE("(%p)\n", This
);
359 static const IInternetProtocolVtbl AboutProtocolVtbl
= {
360 AboutProtocol_QueryInterface
,
361 AboutProtocol_AddRef
,
362 AboutProtocol_Release
,
364 AboutProtocol_Continue
,
366 AboutProtocol_Terminate
,
367 AboutProtocol_Suspend
,
368 AboutProtocol_Resume
,
371 AboutProtocol_LockRequest
,
372 AboutProtocol_UnlockRequest
375 static HRESULT WINAPI
AboutProtocolFactory_CreateInstance(IClassFactory
*iface
, IUnknown
*pUnkOuter
,
376 REFIID riid
, void **ppv
)
381 TRACE("(%p)->(%p %s %p)\n", iface
, pUnkOuter
, debugstr_guid(riid
), ppv
);
383 ret
= heap_alloc(sizeof(AboutProtocol
));
384 ret
->lpInternetProtocolVtbl
= &AboutProtocolVtbl
;
390 ret
->pUnkOuter
= pUnkOuter
;
394 if(IsEqualGUID(&IID_IUnknown
, riid
))
395 *ppv
= PROTOCOL(ret
);
399 hres
= IInternetProtocol_QueryInterface(PROTOCOL(ret
), riid
, ppv
);
408 static HRESULT WINAPI
AboutProtocolInfo_ParseUrl(IInternetProtocolInfo
*iface
, LPCWSTR pwzUrl
,
409 PARSEACTION ParseAction
, DWORD dwParseFlags
, LPWSTR pwzResult
, DWORD cchResult
,
410 DWORD
* pcchResult
, DWORD dwReserved
)
412 TRACE("%p)->(%s %08x %08x %p %d %p %d)\n", iface
, debugstr_w(pwzUrl
), ParseAction
,
413 dwParseFlags
, pwzResult
, cchResult
, pcchResult
, dwReserved
);
415 if(ParseAction
== PARSE_SECURITY_URL
) {
416 unsigned int len
= strlenW(pwzUrl
);
421 memcpy(pwzResult
, pwzUrl
, (len
+1)*sizeof(WCHAR
));
425 if(ParseAction
== PARSE_DOMAIN
) {
430 *pcchResult
= strlenW(pwzUrl
)+1;
436 return INET_E_DEFAULT_ACTION
;
439 static HRESULT WINAPI
AboutProtocolInfo_QueryInfo(IInternetProtocolInfo
*iface
, LPCWSTR pwzUrl
,
440 QUERYOPTION QueryOption
, DWORD dwQueryFlags
, LPVOID pBuffer
, DWORD cbBuffer
, DWORD
* pcbBuf
,
443 TRACE("%p)->(%s %08x %08x %p %d %p %d)\n", iface
, debugstr_w(pwzUrl
), QueryOption
, dwQueryFlags
, pBuffer
,
444 cbBuffer
, pcbBuf
, dwReserved
);
446 switch(QueryOption
) {
447 case QUERY_CAN_NAVIGATE
:
448 return INET_E_USE_DEFAULT_PROTOCOLHANDLER
;
450 case QUERY_USES_NETWORK
:
451 if(!pBuffer
|| cbBuffer
< sizeof(DWORD
))
454 *(DWORD
*)pBuffer
= 0;
456 *pcbBuf
= sizeof(DWORD
);
460 case QUERY_IS_CACHED
:
461 FIXME("Unsupported option QUERY_IS_CACHED\n");
463 case QUERY_IS_INSTALLEDENTRY
:
464 FIXME("Unsupported option QUERY_IS_INSTALLEDENTRY\n");
466 case QUERY_IS_CACHED_OR_MAPPED
:
467 FIXME("Unsupported option QUERY_IS_CACHED_OR_MAPPED\n");
469 case QUERY_IS_SECURE
:
470 FIXME("Unsupported option QUERY_IS_SECURE\n");
473 FIXME("Unsupported option QUERY_IS_SAFE\n");
475 case QUERY_USES_HISTORYFOLDER
:
476 FIXME("Unsupported option QUERY_USES_HISTORYFOLDER\n");
485 static const IInternetProtocolInfoVtbl AboutProtocolInfoVtbl
= {
486 InternetProtocolInfo_QueryInterface
,
487 InternetProtocolInfo_AddRef
,
488 InternetProtocolInfo_Release
,
489 AboutProtocolInfo_ParseUrl
,
490 InternetProtocolInfo_CombineUrl
,
491 InternetProtocolInfo_CompareUrl
,
492 AboutProtocolInfo_QueryInfo
495 static const IClassFactoryVtbl AboutProtocolFactoryVtbl
= {
496 ClassFactory_QueryInterface
,
498 ClassFactory_Release
,
499 AboutProtocolFactory_CreateInstance
,
500 ClassFactory_LockServer
503 static ProtocolFactory AboutProtocolFactory
= {
504 &AboutProtocolInfoVtbl
,
505 &AboutProtocolFactoryVtbl
508 /********************************************************************
509 * ResProtocol implementation
513 const IInternetProtocolVtbl
*lpInternetProtocolVtbl
;
523 #define PROTOCOL_THIS(iface) DEFINE_THIS(ResProtocol, InternetProtocol, iface)
525 static HRESULT WINAPI
ResProtocol_QueryInterface(IInternetProtocol
*iface
, REFIID riid
, void **ppv
)
527 ResProtocol
*This
= PROTOCOL_THIS(iface
);
531 if(IsEqualGUID(&IID_IUnknown
, riid
)) {
532 TRACE("(%p)->(IID_IUnknown %p)\n", iface
, ppv
);
534 return IUnknown_QueryInterface(This
->pUnkOuter
, &IID_IUnknown
, ppv
);
535 *ppv
= PROTOCOL(This
);
536 }else if(IsEqualGUID(&IID_IInternetProtocolRoot
, riid
)) {
537 TRACE("(%p)->(IID_IInternetProtocolRoot %p)\n", iface
, ppv
);
538 *ppv
= PROTOCOL(This
);
539 }else if(IsEqualGUID(&IID_IInternetProtocol
, riid
)) {
540 TRACE("(%p)->(IID_IInternetProtocol %p)\n", iface
, ppv
);
541 *ppv
= PROTOCOL(This
);
542 }else if(IsEqualGUID(&IID_IServiceProvider
, riid
)) {
543 FIXME("IServiceProvider is not implemented\n");
544 return E_NOINTERFACE
;
548 TRACE("unknown interface %s\n", debugstr_guid(riid
));
549 return E_NOINTERFACE
;
552 IInternetProtocol_AddRef(iface
);
556 static ULONG WINAPI
ResProtocol_AddRef(IInternetProtocol
*iface
)
558 ResProtocol
*This
= PROTOCOL_THIS(iface
);
559 ULONG ref
= InterlockedIncrement(&This
->ref
);
560 TRACE("(%p) ref=%d\n", iface
, ref
);
561 return This
->pUnkOuter
? IUnknown_AddRef(This
->pUnkOuter
) : ref
;
564 static ULONG WINAPI
ResProtocol_Release(IInternetProtocol
*iface
)
566 ResProtocol
*This
= (ResProtocol
*)iface
;
567 IUnknown
*pUnkOuter
= This
->pUnkOuter
;
568 ULONG ref
= InterlockedDecrement(&This
->ref
);
570 TRACE("(%p) ref=%x\n", iface
, ref
);
573 heap_free(This
->data
);
577 return pUnkOuter
? IUnknown_Release(pUnkOuter
) : ref
;
580 static HRESULT WINAPI
ResProtocol_Start(IInternetProtocol
*iface
, LPCWSTR szUrl
,
581 IInternetProtocolSink
* pOIProtSink
, IInternetBindInfo
* pOIBindInfo
,
582 DWORD grfPI
, HANDLE_PTR dwReserved
)
584 ResProtocol
*This
= PROTOCOL_THIS(iface
);
585 DWORD grfBINDF
= 0, len
;
587 LPWSTR url_dll
, url_file
, url
, mime
, res_type
= (LPWSTR
)RT_HTML
;
592 static const WCHAR wszRes
[] = {'r','e','s',':','/','/'};
594 TRACE("(%p)->(%s %p %p %08x %lx)\n", This
, debugstr_w(szUrl
), pOIProtSink
,
595 pOIBindInfo
, grfPI
, dwReserved
);
597 memset(&bindinfo
, 0, sizeof(bindinfo
));
598 bindinfo
.cbSize
= sizeof(BINDINFO
);
599 IInternetBindInfo_GetBindInfo(pOIBindInfo
, &grfBINDF
, &bindinfo
);
600 ReleaseBindInfo(&bindinfo
);
602 len
= strlenW(szUrl
)+16;
603 url
= heap_alloc(len
*sizeof(WCHAR
));
604 hres
= CoInternetParseUrl(szUrl
, PARSE_ENCODE
, 0, url
, len
, &len
, 0);
606 WARN("CoInternetParseUrl failed: %08x\n", hres
);
608 IInternetProtocolSink_ReportResult(pOIProtSink
, hres
, 0, NULL
);
612 if(len
< sizeof(wszRes
)/sizeof(wszRes
[0]) || memcmp(url
, wszRes
, sizeof(wszRes
))) {
613 WARN("Wrong protocol of url: %s\n", debugstr_w(url
));
614 IInternetProtocolSink_ReportResult(pOIProtSink
, E_INVALIDARG
, 0, NULL
);
619 url_dll
= url
+ sizeof(wszRes
)/sizeof(wszRes
[0]);
620 if(!(url_file
= strrchrW(url_dll
, '/'))) {
621 WARN("wrong url: %s\n", debugstr_w(url
));
622 IInternetProtocolSink_ReportResult(pOIProtSink
, MK_E_SYNTAX
, 0, NULL
);
628 hdll
= LoadLibraryExW(url_dll
, NULL
, LOAD_LIBRARY_AS_DATAFILE
);
630 if (!(res_type
= strrchrW(url_dll
, '/'))) {
631 WARN("Could not open dll: %s\n", debugstr_w(url_dll
));
632 IInternetProtocolSink_ReportResult(pOIProtSink
, HRESULT_FROM_WIN32(GetLastError()), 0, NULL
);
634 return HRESULT_FROM_WIN32(GetLastError());
638 hdll
= LoadLibraryExW(url_dll
, NULL
, LOAD_LIBRARY_AS_DATAFILE
);
640 WARN("Could not open dll: %s\n", debugstr_w(url_dll
));
641 IInternetProtocolSink_ReportResult(pOIProtSink
, HRESULT_FROM_WIN32(GetLastError()), 0, NULL
);
643 return HRESULT_FROM_WIN32(GetLastError());
647 TRACE("trying to find resource type %s, name %s\n", debugstr_w(res_type
), debugstr_w(url_file
));
649 src
= FindResourceW(hdll
, url_file
, res_type
);
651 LPWSTR endpoint
= NULL
;
652 DWORD file_id
= strtolW(url_file
, &endpoint
, 10);
653 if(endpoint
== url_file
+strlenW(url_file
))
654 src
= FindResourceW(hdll
, MAKEINTRESOURCEW(file_id
), MAKEINTRESOURCEW(RT_HTML
));
657 WARN("Could not find resource\n");
658 IInternetProtocolSink_ReportResult(pOIProtSink
,
659 HRESULT_FROM_WIN32(GetLastError()), 0, NULL
);
661 return HRESULT_FROM_WIN32(GetLastError());
666 WARN("data already loaded\n");
667 heap_free(This
->data
);
670 This
->data_len
= SizeofResource(hdll
, src
);
671 This
->data
= heap_alloc(This
->data_len
);
672 memcpy(This
->data
, LoadResource(hdll
, src
), This
->data_len
);
677 hres
= FindMimeFromData(NULL
, url_file
, This
->data
, This
->data_len
, NULL
, 0, &mime
, 0);
679 if(SUCCEEDED(hres
)) {
680 IInternetProtocolSink_ReportProgress(pOIProtSink
, BINDSTATUS_MIMETYPEAVAILABLE
, mime
);
684 IInternetProtocolSink_ReportData(pOIProtSink
,
685 BSCF_FIRSTDATANOTIFICATION
| BSCF_LASTDATANOTIFICATION
| BSCF_DATAFULLYAVAILABLE
,
686 This
->data_len
, This
->data_len
);
688 IInternetProtocolSink_ReportResult(pOIProtSink
, S_OK
, 0, NULL
);
693 static HRESULT WINAPI
ResProtocol_Continue(IInternetProtocol
*iface
, PROTOCOLDATA
* pProtocolData
)
695 ResProtocol
*This
= PROTOCOL_THIS(iface
);
696 FIXME("(%p)->(%p)\n", This
, pProtocolData
);
700 static HRESULT WINAPI
ResProtocol_Abort(IInternetProtocol
*iface
, HRESULT hrReason
,
703 ResProtocol
*This
= PROTOCOL_THIS(iface
);
704 FIXME("(%p)->(%08x %08x)\n", This
, hrReason
, dwOptions
);
708 static HRESULT WINAPI
ResProtocol_Terminate(IInternetProtocol
*iface
, DWORD dwOptions
)
710 ResProtocol
*This
= PROTOCOL_THIS(iface
);
712 TRACE("(%p)->(%08x)\n", This
, dwOptions
);
714 /* test show that we don't have to do anything here */
718 static HRESULT WINAPI
ResProtocol_Suspend(IInternetProtocol
*iface
)
720 ResProtocol
*This
= PROTOCOL_THIS(iface
);
721 FIXME("(%p)\n", This
);
725 static HRESULT WINAPI
ResProtocol_Resume(IInternetProtocol
*iface
)
727 ResProtocol
*This
= PROTOCOL_THIS(iface
);
728 FIXME("(%p)\n", This
);
732 static HRESULT WINAPI
ResProtocol_Read(IInternetProtocol
*iface
, void* pv
, ULONG cb
, ULONG
* pcbRead
)
734 ResProtocol
*This
= PROTOCOL_THIS(iface
);
736 TRACE("(%p)->(%p %u %p)\n", This
, pv
, cb
, pcbRead
);
741 *pcbRead
= (cb
> This
->data_len
-This
->cur
? This
->data_len
-This
->cur
: cb
);
746 memcpy(pv
, This
->data
+This
->cur
, *pcbRead
);
747 This
->cur
+= *pcbRead
;
752 static HRESULT WINAPI
ResProtocol_Seek(IInternetProtocol
*iface
, LARGE_INTEGER dlibMove
,
753 DWORD dwOrigin
, ULARGE_INTEGER
* plibNewPosition
)
755 ResProtocol
*This
= PROTOCOL_THIS(iface
);
756 FIXME("(%p)->(%d %d %p)\n", This
, dlibMove
.u
.LowPart
, dwOrigin
, plibNewPosition
);
760 static HRESULT WINAPI
ResProtocol_LockRequest(IInternetProtocol
*iface
, DWORD dwOptions
)
762 ResProtocol
*This
= PROTOCOL_THIS(iface
);
764 TRACE("(%p)->(%d)\n", This
, dwOptions
);
766 /* test show that we don't have to do anything here */
770 static HRESULT WINAPI
ResProtocol_UnlockRequest(IInternetProtocol
*iface
)
772 ResProtocol
*This
= PROTOCOL_THIS(iface
);
774 TRACE("(%p)\n", This
);
776 /* test show that we don't have to do anything here */
782 static const IInternetProtocolVtbl ResProtocolVtbl
= {
783 ResProtocol_QueryInterface
,
787 ResProtocol_Continue
,
789 ResProtocol_Terminate
,
794 ResProtocol_LockRequest
,
795 ResProtocol_UnlockRequest
798 static HRESULT WINAPI
ResProtocolFactory_CreateInstance(IClassFactory
*iface
, IUnknown
*pUnkOuter
,
799 REFIID riid
, void **ppv
)
804 TRACE("(%p)->(%p %s %p)\n", iface
, pUnkOuter
, debugstr_guid(riid
), ppv
);
806 ret
= heap_alloc(sizeof(ResProtocol
));
807 ret
->lpInternetProtocolVtbl
= &ResProtocolVtbl
;
812 ret
->pUnkOuter
= pUnkOuter
;
816 if(IsEqualGUID(&IID_IUnknown
, riid
))
817 *ppv
= PROTOCOL(ret
);
821 hres
= IInternetProtocol_QueryInterface(PROTOCOL(ret
), riid
, ppv
);
830 static HRESULT WINAPI
ResProtocolInfo_ParseUrl(IInternetProtocolInfo
*iface
, LPCWSTR pwzUrl
,
831 PARSEACTION ParseAction
, DWORD dwParseFlags
, LPWSTR pwzResult
, DWORD cchResult
,
832 DWORD
* pcchResult
, DWORD dwReserved
)
834 TRACE("%p)->(%s %d %x %p %d %p %d)\n", iface
, debugstr_w(pwzUrl
), ParseAction
,
835 dwParseFlags
, pwzResult
, cchResult
, pcchResult
, dwReserved
);
837 if(ParseAction
== PARSE_SECURITY_URL
) {
838 WCHAR file_part
[MAX_PATH
], full_path
[MAX_PATH
];
842 static const WCHAR wszFile
[] = {'f','i','l','e',':','/','/'};
843 static const WCHAR wszRes
[] = {'r','e','s',':','/','/'};
845 if(strlenW(pwzUrl
) <= sizeof(wszRes
)/sizeof(WCHAR
) || memcmp(pwzUrl
, wszRes
, sizeof(wszRes
)))
848 ptr
= strchrW(pwzUrl
+ sizeof(wszRes
)/sizeof(WCHAR
), '/');
852 len
= ptr
- (pwzUrl
+ sizeof(wszRes
)/sizeof(WCHAR
));
853 if(len
>= sizeof(file_part
)/sizeof(WCHAR
)) {
854 FIXME("Too long URL\n");
858 memcpy(file_part
, pwzUrl
+ sizeof(wszRes
)/sizeof(WCHAR
), len
*sizeof(WCHAR
));
861 len
= SearchPathW(NULL
, file_part
, NULL
, sizeof(full_path
)/sizeof(WCHAR
), full_path
, NULL
);
863 WARN("Could not find file %s\n", debugstr_w(file_part
));
867 size
= sizeof(wszFile
)/sizeof(WCHAR
) + len
+ 1;
870 if(size
>= cchResult
)
873 memcpy(pwzResult
, wszFile
, sizeof(wszFile
));
874 memcpy(pwzResult
+ sizeof(wszFile
)/sizeof(WCHAR
), full_path
, (len
+1)*sizeof(WCHAR
));
878 if(ParseAction
== PARSE_DOMAIN
) {
883 *pcchResult
= strlenW(pwzUrl
)+1;
889 return INET_E_DEFAULT_ACTION
;
892 static HRESULT WINAPI
ResProtocolInfo_QueryInfo(IInternetProtocolInfo
*iface
, LPCWSTR pwzUrl
,
893 QUERYOPTION QueryOption
, DWORD dwQueryFlags
, LPVOID pBuffer
, DWORD cbBuffer
, DWORD
* pcbBuf
,
896 TRACE("%p)->(%s %08x %08x %p %d %p %d)\n", iface
, debugstr_w(pwzUrl
), QueryOption
, dwQueryFlags
, pBuffer
,
897 cbBuffer
, pcbBuf
, dwReserved
);
899 switch(QueryOption
) {
900 case QUERY_USES_NETWORK
:
901 if(!pBuffer
|| cbBuffer
< sizeof(DWORD
))
904 *(DWORD
*)pBuffer
= 0;
906 *pcbBuf
= sizeof(DWORD
);
909 case QUERY_IS_SECURE
:
910 FIXME("not supporte QUERY_IS_SECURE\n");
913 FIXME("not supporte QUERY_IS_SAFE\n");
916 return INET_E_USE_DEFAULT_PROTOCOLHANDLER
;
922 static const IInternetProtocolInfoVtbl ResProtocolInfoVtbl
= {
923 InternetProtocolInfo_QueryInterface
,
924 InternetProtocolInfo_AddRef
,
925 InternetProtocolInfo_Release
,
926 ResProtocolInfo_ParseUrl
,
927 InternetProtocolInfo_CombineUrl
,
928 InternetProtocolInfo_CompareUrl
,
929 ResProtocolInfo_QueryInfo
932 static const IClassFactoryVtbl ResProtocolFactoryVtbl
= {
933 ClassFactory_QueryInterface
,
935 ClassFactory_Release
,
936 ResProtocolFactory_CreateInstance
,
937 ClassFactory_LockServer
940 static ProtocolFactory ResProtocolFactory
= {
941 &ResProtocolInfoVtbl
,
942 &ResProtocolFactoryVtbl
945 /********************************************************************
946 * JSProtocol implementation
949 static HRESULT WINAPI
JSProtocolFactory_CreateInstance(IClassFactory
*iface
, IUnknown
*pUnkOuter
,
950 REFIID riid
, void **ppv
)
952 FIXME("(%p)->(%p %s %p)\n", iface
, pUnkOuter
, debugstr_guid(riid
), ppv
);
956 static HRESULT WINAPI
JSProtocolInfo_ParseUrl(IInternetProtocolInfo
*iface
, LPCWSTR pwzUrl
,
957 PARSEACTION ParseAction
, DWORD dwParseFlags
, LPWSTR pwzResult
, DWORD cchResult
,
958 DWORD
* pcchResult
, DWORD dwReserved
)
960 TRACE("%p)->(%s %d %x %p %d %p %d)\n", iface
, debugstr_w(pwzUrl
), ParseAction
,
961 dwParseFlags
, pwzResult
, cchResult
, pcchResult
, dwReserved
);
963 switch(ParseAction
) {
964 case PARSE_SECURITY_URL
:
965 FIXME("PARSE_SECURITY_URL\n");
968 FIXME("PARSE_DOMAIN\n");
971 return INET_E_DEFAULT_ACTION
;
977 static HRESULT WINAPI
JSProtocolInfo_QueryInfo(IInternetProtocolInfo
*iface
, LPCWSTR pwzUrl
,
978 QUERYOPTION QueryOption
, DWORD dwQueryFlags
, LPVOID pBuffer
, DWORD cbBuffer
, DWORD
* pcbBuf
,
981 TRACE("%p)->(%s %08x %08x %p %d %p %d)\n", iface
, debugstr_w(pwzUrl
), QueryOption
, dwQueryFlags
, pBuffer
,
982 cbBuffer
, pcbBuf
, dwReserved
);
984 switch(QueryOption
) {
985 case QUERY_USES_NETWORK
:
986 if(!pBuffer
|| cbBuffer
< sizeof(DWORD
))
989 *(DWORD
*)pBuffer
= 0;
991 *pcbBuf
= sizeof(DWORD
);
994 case QUERY_IS_SECURE
:
995 FIXME("not supporte QUERY_IS_SECURE\n");
999 return INET_E_USE_DEFAULT_PROTOCOLHANDLER
;
1005 static const IInternetProtocolInfoVtbl JSProtocolInfoVtbl
= {
1006 InternetProtocolInfo_QueryInterface
,
1007 InternetProtocolInfo_AddRef
,
1008 InternetProtocolInfo_Release
,
1009 JSProtocolInfo_ParseUrl
,
1010 InternetProtocolInfo_CombineUrl
,
1011 InternetProtocolInfo_CompareUrl
,
1012 JSProtocolInfo_QueryInfo
1015 static const IClassFactoryVtbl JSProtocolFactoryVtbl
= {
1016 ClassFactory_QueryInterface
,
1017 ClassFactory_AddRef
,
1018 ClassFactory_Release
,
1019 JSProtocolFactory_CreateInstance
,
1020 ClassFactory_LockServer
1023 static ProtocolFactory JSProtocolFactory
= {
1024 &JSProtocolInfoVtbl
,
1025 &JSProtocolFactoryVtbl
1028 HRESULT
ProtocolFactory_Create(REFCLSID rclsid
, REFIID riid
, void **ppv
)
1030 ProtocolFactory
*cf
= NULL
;
1032 if(IsEqualGUID(&CLSID_AboutProtocol
, rclsid
))
1033 cf
= &AboutProtocolFactory
;
1034 else if(IsEqualGUID(&CLSID_ResProtocol
, rclsid
))
1035 cf
= &ResProtocolFactory
;
1036 else if(IsEqualGUID(&CLSID_JSProtocol
, rclsid
))
1037 cf
= &JSProtocolFactory
;
1040 FIXME("not implemented protocol %s\n", debugstr_guid(rclsid
));
1041 return CLASS_E_CLASSNOTAVAILABLE
;
1044 return IUnknown_QueryInterface((IUnknown
*)cf
, riid
, ppv
);