mirror of
https://github.com/reactos/reactos.git
synced 2025-01-04 21:38:43 +00:00
[INETCOMM] Sync with Wine Staging 2.2. CORE-12823
51e1a08 inetcomm: Return S_FALSE if no data is returned in IInternetProtocol::Read. 0672bfa inetcomm: Added support for decoding quoted-printable data. 07af9d0 inetcomm: Added mhtml binding tests. cf8e259 inetcomm: Added support for binding mhtml protocol handler. 3f644cb inetcomm: Added IInternetProtocolInfo::CombineUrl implementation. 37792a2 inetcomm: Added MimeOleObjectFromMoniker semi-stub implementation. 242cbb1 inetcomm: Added tests reading MHTML page as MIME message. eb0bd22 inetcomm: Removed unneeded type check in init_content_type. 56dc246 inetcomm: Read content encoding from MIME header. dec243f inetcomm: Don't include headers in data stream in create_sub_body. 3ccba10 inetcomm: Properly handle boundary in the beginning of body stream in create_body_offset_list. 9c01a94 inetcomm: Use relative seek in copy_headers_to_buf. 915acd6 inetcomm: Added support for decoding base64 in IMimeBody::GetData. 0b80666 inetcomm: Return a new instance of stream in IMimeBody::GetData. 393512d inetcomm: Don't restore base stream position in sub stream Read. bb5056e inetcomm: Moved sub_stream_t implementation before MimeBody implementation. a1d0c6d inetcomm: Added COM aggregation support to MimeHtmlProtocol object. fe3e5b9 inetcomm: Added IInternetProtocolInfo stub implementation. 6832273 inetcomm: Added MimeHtmlProtocol stub implementation. d5d9aa3 inetcomm: Register mhtml protocol handler. svn path=/trunk/; revision=74105
This commit is contained in:
parent
48277d058b
commit
8e07a66b68
9 changed files with 1413 additions and 340 deletions
|
@ -10,6 +10,7 @@ list(APPEND SOURCE
|
||||||
mimeintl.c
|
mimeintl.c
|
||||||
mimeole.c
|
mimeole.c
|
||||||
pop3transport.c
|
pop3transport.c
|
||||||
|
protocol.c
|
||||||
smtptransport.c
|
smtptransport.c
|
||||||
inetcomm_private.h)
|
inetcomm_private.h)
|
||||||
|
|
||||||
|
@ -22,6 +23,6 @@ add_library(inetcomm SHARED
|
||||||
|
|
||||||
set_module_type(inetcomm win32dll)
|
set_module_type(inetcomm win32dll)
|
||||||
target_link_libraries(inetcomm uuid wine)
|
target_link_libraries(inetcomm uuid wine)
|
||||||
add_importlibs(inetcomm ole32 oleaut32 ws2_32 user32 propsys msvcrt kernel32 ntdll)
|
add_importlibs(inetcomm ole32 oleaut32 ws2_32 user32 propsys urlmon msvcrt kernel32 ntdll)
|
||||||
add_pch(inetcomm inetcomm_private.h SOURCE)
|
add_pch(inetcomm inetcomm_private.h SOURCE)
|
||||||
add_cd_file(TARGET inetcomm DESTINATION reactos/system32 FOR all)
|
add_cd_file(TARGET inetcomm DESTINATION reactos/system32 FOR all)
|
||||||
|
|
|
@ -124,3 +124,10 @@ coclass IPropFindRequest { interface IPropFindRequest; }
|
||||||
uuid(ea678830-235d-11d2-a8b6-0000f8084f96)
|
uuid(ea678830-235d-11d2-a8b6-0000f8084f96)
|
||||||
]
|
]
|
||||||
coclass IPropPatchRequest { interface IPropPatchRequest; }
|
coclass IPropPatchRequest { interface IPropPatchRequest; }
|
||||||
|
|
||||||
|
[
|
||||||
|
helpstring("MHTML Asynchronous Pluggable Protocol Handler"),
|
||||||
|
threading(both),
|
||||||
|
uuid(05300401-bcbc-11d0-85e3-00c04fd85ab4)
|
||||||
|
]
|
||||||
|
coclass MimeHtmlProtocol { interface IInternetProtocol; }
|
||||||
|
|
|
@ -1 +1,22 @@
|
||||||
1 WINE_REGISTRY "inetcomm.rgs"
|
/*
|
||||||
|
* Copyright 2016 Jacek Caban for CodeWeavers
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* @makedep: inetcomm.rgs */
|
||||||
|
1 WINE_REGISTRY inetcomm.rgs
|
||||||
|
|
||||||
|
2 WINE_REGISTRY inetcomm_r.rgs
|
||||||
|
|
|
@ -74,7 +74,9 @@ static HRESULT WINAPI cf_QueryInterface( IClassFactory *iface, REFIID riid, LPVO
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
FIXME("interface %s not implemented\n", debugstr_guid(riid));
|
if (!IsEqualGUID(riid, &IID_IInternetProtocolInfo))
|
||||||
|
FIXME("interface %s not implemented\n", debugstr_guid(riid));
|
||||||
|
*ppobj = NULL;
|
||||||
return E_NOINTERFACE;
|
return E_NOINTERFACE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,13 +101,20 @@ static HRESULT WINAPI cf_CreateInstance( IClassFactory *iface, LPUNKNOWN pOuter,
|
||||||
|
|
||||||
*ppobj = NULL;
|
*ppobj = NULL;
|
||||||
|
|
||||||
|
if (pOuter && !IsEqualGUID(&IID_IUnknown, riid))
|
||||||
|
return CLASS_E_NOAGGREGATION;
|
||||||
|
|
||||||
r = This->create_object( pOuter, (LPVOID*) &punk );
|
r = This->create_object( pOuter, (LPVOID*) &punk );
|
||||||
if (FAILED(r))
|
if (FAILED(r))
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
if (IsEqualGUID(&IID_IUnknown, riid)) {
|
||||||
|
*ppobj = punk;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
r = IUnknown_QueryInterface( punk, riid, ppobj );
|
r = IUnknown_QueryInterface( punk, riid, ppobj );
|
||||||
IUnknown_Release( punk );
|
IUnknown_Release( punk );
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,6 +138,7 @@ static cf mime_allocator_cf = { { &cf_vtbl }, MimeAllocator_create };
|
||||||
static cf mime_message_cf = { { &cf_vtbl }, MimeMessage_create };
|
static cf mime_message_cf = { { &cf_vtbl }, MimeMessage_create };
|
||||||
static cf mime_security_cf = { { &cf_vtbl }, MimeSecurity_create };
|
static cf mime_security_cf = { { &cf_vtbl }, MimeSecurity_create };
|
||||||
static cf virtual_stream_cf = { { &cf_vtbl }, VirtualStream_create };
|
static cf virtual_stream_cf = { { &cf_vtbl }, VirtualStream_create };
|
||||||
|
static cf mhtml_protocol_cf = { { &cf_vtbl }, MimeHtmlProtocol_create };
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* DllGetClassObject (INETCOMM.@)
|
* DllGetClassObject (INETCOMM.@)
|
||||||
|
@ -171,6 +181,10 @@ HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv)
|
||||||
{
|
{
|
||||||
cf = &virtual_stream_cf.IClassFactory_iface;
|
cf = &virtual_stream_cf.IClassFactory_iface;
|
||||||
}
|
}
|
||||||
|
else if( IsEqualCLSID( rclsid, &CLSID_IMimeHtmlProtocol ))
|
||||||
|
{
|
||||||
|
cf = &mhtml_protocol_cf.IClassFactory_iface;
|
||||||
|
}
|
||||||
|
|
||||||
if ( !cf )
|
if ( !cf )
|
||||||
{
|
{
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
#include <imnxport.h>
|
#include <imnxport.h>
|
||||||
|
|
||||||
#include <wine/list.h>
|
#include <wine/list.h>
|
||||||
|
#include <wine/unicode.h>
|
||||||
|
|
||||||
#include <wine/debug.h>
|
#include <wine/debug.h>
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(inetcomm);
|
WINE_DEFAULT_DEBUG_CHANNEL(inetcomm);
|
||||||
|
@ -95,6 +96,7 @@ HRESULT MimeAllocator_create(IUnknown *outer, void **obj) DECLSPEC_HIDDEN;
|
||||||
HRESULT MimeMessage_create(IUnknown *outer, void **obj) DECLSPEC_HIDDEN;
|
HRESULT MimeMessage_create(IUnknown *outer, void **obj) DECLSPEC_HIDDEN;
|
||||||
HRESULT MimeSecurity_create(IUnknown *outer, void **obj) DECLSPEC_HIDDEN;
|
HRESULT MimeSecurity_create(IUnknown *outer, void **obj) DECLSPEC_HIDDEN;
|
||||||
HRESULT VirtualStream_create(IUnknown *outer, void **obj) DECLSPEC_HIDDEN;
|
HRESULT VirtualStream_create(IUnknown *outer, void **obj) DECLSPEC_HIDDEN;
|
||||||
|
HRESULT MimeHtmlProtocol_create(IUnknown *outer, void **obj) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
HRESULT MimeInternational_Construct(IMimeInternational **internat) DECLSPEC_HIDDEN;
|
HRESULT MimeInternational_Construct(IMimeInternational **internat) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
|
@ -102,4 +104,14 @@ HRESULT SMTPTransportCF_Create(REFIID riid, LPVOID *ppv) DECLSPEC_HIDDEN;
|
||||||
HRESULT IMAPTransportCF_Create(REFIID riid, LPVOID *ppv) DECLSPEC_HIDDEN;
|
HRESULT IMAPTransportCF_Create(REFIID riid, LPVOID *ppv) DECLSPEC_HIDDEN;
|
||||||
HRESULT POP3TransportCF_Create(REFIID riid, LPVOID *ppv) DECLSPEC_HIDDEN;
|
HRESULT POP3TransportCF_Create(REFIID riid, LPVOID *ppv) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
|
static inline void * __WINE_ALLOC_SIZE(1) heap_alloc(size_t len)
|
||||||
|
{
|
||||||
|
return HeapAlloc(GetProcessHeap(), 0, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline BOOL heap_free(void *mem)
|
||||||
|
{
|
||||||
|
return HeapFree(GetProcessHeap(), 0, mem);
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* _INETCOMM_PRIVATE_H_ */
|
#endif /* _INETCOMM_PRIVATE_H_ */
|
||||||
|
|
|
@ -65,5 +65,9 @@ HKCR
|
||||||
{
|
{
|
||||||
InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' }
|
InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' }
|
||||||
}
|
}
|
||||||
|
'{05300401-BCBC-11D0-85E3-00C04FD85AB4}' = s 'MHTML Asynchronous Pluggable Protocol Handler'
|
||||||
|
{
|
||||||
|
InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Both' }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
File diff suppressed because it is too large
Load diff
738
reactos/dll/win32/inetcomm/protocol.c
Normal file
738
reactos/dll/win32/inetcomm/protocol.c
Normal file
|
@ -0,0 +1,738 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2017 Jacek Caban for CodeWeavers
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "inetcomm_private.h"
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
IUnknown IUnknown_inner;
|
||||||
|
IInternetProtocol IInternetProtocol_iface;
|
||||||
|
IInternetProtocolInfo IInternetProtocolInfo_iface;
|
||||||
|
|
||||||
|
LONG ref;
|
||||||
|
IUnknown *outer_unk;
|
||||||
|
|
||||||
|
WCHAR *location;
|
||||||
|
IStream *stream;
|
||||||
|
IInternetProtocolSink *sink;
|
||||||
|
} MimeHtmlProtocol;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
const WCHAR *mhtml;
|
||||||
|
size_t mhtml_len;
|
||||||
|
const WCHAR *location;
|
||||||
|
} mhtml_url_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
IBindStatusCallback IBindStatusCallback_iface;
|
||||||
|
|
||||||
|
LONG ref;
|
||||||
|
|
||||||
|
MimeHtmlProtocol *protocol;
|
||||||
|
HRESULT status;
|
||||||
|
IStream *stream;
|
||||||
|
WCHAR url[1];
|
||||||
|
} MimeHtmlBinding;
|
||||||
|
|
||||||
|
static const WCHAR mhtml_prefixW[] = {'m','h','t','m','l',':'};
|
||||||
|
static const WCHAR mhtml_separatorW[] = {'!','x','-','u','s','c',':'};
|
||||||
|
|
||||||
|
static inline LPWSTR heap_strdupW(LPCWSTR str)
|
||||||
|
{
|
||||||
|
LPWSTR ret = NULL;
|
||||||
|
|
||||||
|
if(str) {
|
||||||
|
DWORD size;
|
||||||
|
|
||||||
|
size = (strlenW(str)+1)*sizeof(WCHAR);
|
||||||
|
ret = heap_alloc(size);
|
||||||
|
if(ret)
|
||||||
|
memcpy(ret, str, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT parse_mhtml_url(const WCHAR *url, mhtml_url_t *r)
|
||||||
|
{
|
||||||
|
const WCHAR *p;
|
||||||
|
|
||||||
|
if(strncmpiW(url, mhtml_prefixW, sizeof(mhtml_prefixW)/sizeof(WCHAR)))
|
||||||
|
return E_FAIL;
|
||||||
|
|
||||||
|
r->mhtml = url + sizeof(mhtml_prefixW)/sizeof(WCHAR);
|
||||||
|
p = strchrW(r->mhtml, '!');
|
||||||
|
if(p) {
|
||||||
|
r->mhtml_len = p - r->mhtml;
|
||||||
|
/* FIXME: We handle '!' and '!x-usc:' in URLs as the same thing. Those should not be the same. */
|
||||||
|
if(!strncmpW(p, mhtml_separatorW, sizeof(mhtml_separatorW)/sizeof(WCHAR)))
|
||||||
|
p += sizeof(mhtml_separatorW)/sizeof(WCHAR);
|
||||||
|
else
|
||||||
|
p++;
|
||||||
|
}else {
|
||||||
|
r->mhtml_len = strlenW(r->mhtml);
|
||||||
|
}
|
||||||
|
|
||||||
|
r->location = p;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT report_result(MimeHtmlProtocol *protocol, HRESULT result)
|
||||||
|
{
|
||||||
|
if(protocol->sink) {
|
||||||
|
IInternetProtocolSink_ReportResult(protocol->sink, result, ERROR_SUCCESS, NULL);
|
||||||
|
IInternetProtocolSink_Release(protocol->sink);
|
||||||
|
protocol->sink = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT on_mime_message_available(MimeHtmlProtocol *protocol, IMimeMessage *mime_message)
|
||||||
|
{
|
||||||
|
FINDBODY find = {NULL};
|
||||||
|
IMimeBody *mime_body;
|
||||||
|
PROPVARIANT value;
|
||||||
|
HBODY body;
|
||||||
|
HRESULT hres;
|
||||||
|
|
||||||
|
hres = IMimeMessage_FindFirst(mime_message, &find, &body);
|
||||||
|
if(FAILED(hres))
|
||||||
|
return report_result(protocol, hres);
|
||||||
|
|
||||||
|
if(protocol->location) {
|
||||||
|
BOOL found = FALSE;
|
||||||
|
do {
|
||||||
|
hres = IMimeMessage_FindNext(mime_message, &find, &body);
|
||||||
|
if(FAILED(hres)) {
|
||||||
|
WARN("location %s not found\n", debugstr_w(protocol->location));
|
||||||
|
return report_result(protocol, hres);
|
||||||
|
}
|
||||||
|
|
||||||
|
value.vt = VT_LPWSTR;
|
||||||
|
hres = IMimeMessage_GetBodyProp(mime_message, body, "content-location", 0, &value);
|
||||||
|
if(hres == MIME_E_NOT_FOUND)
|
||||||
|
continue;
|
||||||
|
if(FAILED(hres))
|
||||||
|
return report_result(protocol, hres);
|
||||||
|
|
||||||
|
found = !strcmpW(protocol->location, value.u.pwszVal);
|
||||||
|
PropVariantClear(&value);
|
||||||
|
}while(!found);
|
||||||
|
}else {
|
||||||
|
hres = IMimeMessage_FindNext(mime_message, &find, &body);
|
||||||
|
if(FAILED(hres)) {
|
||||||
|
WARN("location %s not found\n", debugstr_w(protocol->location));
|
||||||
|
return report_result(protocol, hres);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hres = IMimeMessage_BindToObject(mime_message, body, &IID_IMimeBody, (void**)&mime_body);
|
||||||
|
if(FAILED(hres))
|
||||||
|
return report_result(protocol, hres);
|
||||||
|
|
||||||
|
value.vt = VT_LPWSTR;
|
||||||
|
hres = IMimeBody_GetProp(mime_body, "content-type", 0, &value);
|
||||||
|
if(SUCCEEDED(hres)) {
|
||||||
|
hres = IInternetProtocolSink_ReportProgress(protocol->sink, BINDSTATUS_MIMETYPEAVAILABLE, value.u.pwszVal);
|
||||||
|
PropVariantClear(&value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* FIXME: Create and report cache file. */
|
||||||
|
|
||||||
|
hres = IMimeBody_GetData(mime_body, IET_DECODED, &protocol->stream);
|
||||||
|
if(FAILED(hres))
|
||||||
|
return report_result(protocol, hres);
|
||||||
|
|
||||||
|
IInternetProtocolSink_ReportData(protocol->sink, BSCF_FIRSTDATANOTIFICATION
|
||||||
|
| BSCF_INTERMEDIATEDATANOTIFICATION
|
||||||
|
| BSCF_LASTDATANOTIFICATION
|
||||||
|
| BSCF_DATAFULLYAVAILABLE
|
||||||
|
| BSCF_AVAILABLEDATASIZEUNKNOWN, 0, 0);
|
||||||
|
|
||||||
|
return report_result(protocol, S_OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT load_mime_message(IStream *stream, IMimeMessage **ret)
|
||||||
|
{
|
||||||
|
IMimeMessage *mime_message;
|
||||||
|
HRESULT hres;
|
||||||
|
|
||||||
|
hres = MimeMessage_create(NULL, (void**)&mime_message);
|
||||||
|
if(FAILED(hres))
|
||||||
|
return hres;
|
||||||
|
|
||||||
|
IMimeMessage_InitNew(mime_message);
|
||||||
|
|
||||||
|
hres = IMimeMessage_Load(mime_message, stream);
|
||||||
|
if(FAILED(hres)) {
|
||||||
|
IMimeMessage_Release(mime_message);
|
||||||
|
return hres;
|
||||||
|
}
|
||||||
|
|
||||||
|
*ret = mime_message;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline MimeHtmlBinding *impl_from_IBindStatusCallback(IBindStatusCallback *iface)
|
||||||
|
{
|
||||||
|
return CONTAINING_RECORD(iface, MimeHtmlBinding, IBindStatusCallback_iface);
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI BindStatusCallback_QueryInterface(IBindStatusCallback *iface,
|
||||||
|
REFIID riid, void **ppv)
|
||||||
|
{
|
||||||
|
MimeHtmlBinding *This = impl_from_IBindStatusCallback(iface);
|
||||||
|
|
||||||
|
if(IsEqualGUID(&IID_IUnknown, riid)) {
|
||||||
|
TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
|
||||||
|
*ppv = &This->IBindStatusCallback_iface;
|
||||||
|
}else if(IsEqualGUID(&IID_IBindStatusCallback, riid)) {
|
||||||
|
TRACE("(%p)->(IID_IBindStatusCallback %p)\n", This, ppv);
|
||||||
|
*ppv = &This->IBindStatusCallback_iface;
|
||||||
|
}else {
|
||||||
|
TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
|
||||||
|
*ppv = NULL;
|
||||||
|
return E_NOINTERFACE;
|
||||||
|
}
|
||||||
|
|
||||||
|
IUnknown_AddRef((IUnknown*)*ppv);
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ULONG WINAPI BindStatusCallback_AddRef(IBindStatusCallback *iface)
|
||||||
|
{
|
||||||
|
MimeHtmlBinding *This = impl_from_IBindStatusCallback(iface);
|
||||||
|
LONG ref = InterlockedIncrement(&This->ref);
|
||||||
|
|
||||||
|
TRACE("(%p) ref=%d\n", This, ref);
|
||||||
|
|
||||||
|
return ref;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ULONG WINAPI BindStatusCallback_Release(IBindStatusCallback *iface)
|
||||||
|
{
|
||||||
|
MimeHtmlBinding *This = impl_from_IBindStatusCallback(iface);
|
||||||
|
LONG ref = InterlockedDecrement(&This->ref);
|
||||||
|
|
||||||
|
TRACE("(%p) ref=%d\n", This, ref);
|
||||||
|
|
||||||
|
if(!ref) {
|
||||||
|
if(This->protocol)
|
||||||
|
IInternetProtocol_Release(&This->protocol->IInternetProtocol_iface);
|
||||||
|
if(This->stream)
|
||||||
|
IStream_Release(This->stream);
|
||||||
|
heap_free(This);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ref;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI BindStatusCallback_OnStartBinding(IBindStatusCallback *iface,
|
||||||
|
DWORD dwReserved, IBinding *pib)
|
||||||
|
{
|
||||||
|
MimeHtmlBinding *This = impl_from_IBindStatusCallback(iface);
|
||||||
|
|
||||||
|
TRACE("(%p)->(%x %p)\n", This, dwReserved, pib);
|
||||||
|
|
||||||
|
assert(!This->stream);
|
||||||
|
return CreateStreamOnHGlobal(NULL, TRUE, &This->stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI BindStatusCallback_GetPriority(IBindStatusCallback *iface, LONG *pnPriority)
|
||||||
|
{
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI BindStatusCallback_OnLowResource(IBindStatusCallback *iface, DWORD dwReserved)
|
||||||
|
{
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI BindStatusCallback_OnProgress(IBindStatusCallback *iface, ULONG ulProgress,
|
||||||
|
ULONG ulProgressMax, ULONG ulStatusCode, LPCWSTR szStatusText)
|
||||||
|
{
|
||||||
|
MimeHtmlBinding *This = impl_from_IBindStatusCallback(iface);
|
||||||
|
TRACE("(%p)->(%u/%u %u %s)\n", This, ulProgress, ulProgressMax, ulStatusCode, debugstr_w(szStatusText));
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI BindStatusCallback_OnStopBinding(IBindStatusCallback *iface, HRESULT hresult, LPCWSTR szError)
|
||||||
|
{
|
||||||
|
MimeHtmlBinding *This = impl_from_IBindStatusCallback(iface);
|
||||||
|
IMimeMessage *mime_message = NULL;
|
||||||
|
|
||||||
|
TRACE("(%p)->(%x %s)\n", This, hresult, debugstr_w(szError));
|
||||||
|
|
||||||
|
if(SUCCEEDED(hresult)) {
|
||||||
|
hresult = load_mime_message(This->stream, &mime_message);
|
||||||
|
IStream_Release(This->stream);
|
||||||
|
This->stream = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
This->status = hresult;
|
||||||
|
|
||||||
|
if(mime_message)
|
||||||
|
on_mime_message_available(This->protocol, mime_message);
|
||||||
|
else
|
||||||
|
report_result(This->protocol, hresult);
|
||||||
|
|
||||||
|
if(mime_message)
|
||||||
|
IMimeMessage_Release(mime_message);
|
||||||
|
IInternetProtocol_Release(&This->protocol->IInternetProtocol_iface);
|
||||||
|
This->protocol = NULL;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI BindStatusCallback_GetBindInfo(IBindStatusCallback *iface,
|
||||||
|
DWORD* grfBINDF, BINDINFO* pbindinfo)
|
||||||
|
{
|
||||||
|
MimeHtmlBinding *This = impl_from_IBindStatusCallback(iface);
|
||||||
|
|
||||||
|
TRACE("(%p)\n", This);
|
||||||
|
|
||||||
|
*grfBINDF = BINDF_ASYNCHRONOUS;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI BindStatusCallback_OnDataAvailable(IBindStatusCallback *iface, DWORD grfBSCF,
|
||||||
|
DWORD dwSize, FORMATETC* pformatetc, STGMEDIUM* pstgmed)
|
||||||
|
{
|
||||||
|
MimeHtmlBinding *This = impl_from_IBindStatusCallback(iface);
|
||||||
|
BYTE buf[4*1024];
|
||||||
|
DWORD read;
|
||||||
|
HRESULT hres;
|
||||||
|
|
||||||
|
TRACE("(%p)\n", This);
|
||||||
|
|
||||||
|
assert(pstgmed->tymed == TYMED_ISTREAM);
|
||||||
|
|
||||||
|
while(1) {
|
||||||
|
hres = IStream_Read(pstgmed->u.pstm, buf, sizeof(buf), &read);
|
||||||
|
if(FAILED(hres))
|
||||||
|
return hres;
|
||||||
|
if(!read)
|
||||||
|
break;
|
||||||
|
hres = IStream_Write(This->stream, buf, read, NULL);
|
||||||
|
if(FAILED(hres))
|
||||||
|
return hres;
|
||||||
|
}
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI BindStatusCallback_OnObjectAvailable(IBindStatusCallback *iface,
|
||||||
|
REFIID riid, IUnknown* punk)
|
||||||
|
{
|
||||||
|
ERR("\n");
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const IBindStatusCallbackVtbl BindStatusCallbackVtbl = {
|
||||||
|
BindStatusCallback_QueryInterface,
|
||||||
|
BindStatusCallback_AddRef,
|
||||||
|
BindStatusCallback_Release,
|
||||||
|
BindStatusCallback_OnStartBinding,
|
||||||
|
BindStatusCallback_GetPriority,
|
||||||
|
BindStatusCallback_OnLowResource,
|
||||||
|
BindStatusCallback_OnProgress,
|
||||||
|
BindStatusCallback_OnStopBinding,
|
||||||
|
BindStatusCallback_GetBindInfo,
|
||||||
|
BindStatusCallback_OnDataAvailable,
|
||||||
|
BindStatusCallback_OnObjectAvailable
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline MimeHtmlProtocol *impl_from_IUnknown(IUnknown *iface)
|
||||||
|
{
|
||||||
|
return CONTAINING_RECORD(iface, MimeHtmlProtocol, IUnknown_inner);
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI MimeHtmlProtocol_QueryInterface(IUnknown *iface, REFIID riid, void **ppv)
|
||||||
|
{
|
||||||
|
MimeHtmlProtocol *This = impl_from_IUnknown(iface);
|
||||||
|
|
||||||
|
if(IsEqualGUID(&IID_IUnknown, riid)) {
|
||||||
|
TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
|
||||||
|
*ppv = &This->IInternetProtocol_iface;
|
||||||
|
}else if(IsEqualGUID(&IID_IInternetProtocolRoot, riid)) {
|
||||||
|
TRACE("(%p)->(IID_IInternetProtocolRoot %p)\n", This, ppv);
|
||||||
|
*ppv = &This->IInternetProtocol_iface;
|
||||||
|
}else if(IsEqualGUID(&IID_IInternetProtocol, riid)) {
|
||||||
|
TRACE("(%p)->(IID_IInternetProtocol %p)\n", This, ppv);
|
||||||
|
*ppv = &This->IInternetProtocol_iface;
|
||||||
|
}else if(IsEqualGUID(&IID_IInternetProtocolInfo, riid)) {
|
||||||
|
TRACE("(%p)->(IID_IInternetProtocolInfo %p)\n", This, ppv);
|
||||||
|
*ppv = &This->IInternetProtocolInfo_iface;
|
||||||
|
}else {
|
||||||
|
FIXME("unknown interface %s\n", debugstr_guid(riid));
|
||||||
|
*ppv = NULL;
|
||||||
|
return E_NOINTERFACE;
|
||||||
|
}
|
||||||
|
|
||||||
|
IUnknown_AddRef((IUnknown*)*ppv);
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ULONG WINAPI MimeHtmlProtocol_AddRef(IUnknown *iface)
|
||||||
|
{
|
||||||
|
MimeHtmlProtocol *This = impl_from_IUnknown(iface);
|
||||||
|
ULONG ref = InterlockedIncrement(&This->ref);
|
||||||
|
|
||||||
|
TRACE("(%p) ref=%d\n", This, ref);
|
||||||
|
|
||||||
|
return ref;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ULONG WINAPI MimeHtmlProtocol_Release(IUnknown *iface)
|
||||||
|
{
|
||||||
|
MimeHtmlProtocol *This = impl_from_IUnknown(iface);
|
||||||
|
ULONG ref = InterlockedDecrement(&This->ref);
|
||||||
|
|
||||||
|
TRACE("(%p) ref=%x\n", This, ref);
|
||||||
|
|
||||||
|
if(!ref) {
|
||||||
|
if(This->sink)
|
||||||
|
IInternetProtocolSink_Release(This->sink);
|
||||||
|
if(This->stream)
|
||||||
|
IStream_Release(This->stream);
|
||||||
|
heap_free(This->location);
|
||||||
|
heap_free(This);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ref;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const IUnknownVtbl MimeHtmlProtocolInnerVtbl = {
|
||||||
|
MimeHtmlProtocol_QueryInterface,
|
||||||
|
MimeHtmlProtocol_AddRef,
|
||||||
|
MimeHtmlProtocol_Release
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline MimeHtmlProtocol *impl_from_IInternetProtocol(IInternetProtocol *iface)
|
||||||
|
{
|
||||||
|
return CONTAINING_RECORD(iface, MimeHtmlProtocol, IInternetProtocol_iface);
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI InternetProtocol_QueryInterface(IInternetProtocol *iface, REFIID riid, void **ppv)
|
||||||
|
{
|
||||||
|
MimeHtmlProtocol *This = impl_from_IInternetProtocol(iface);
|
||||||
|
return IUnknown_QueryInterface(This->outer_unk, riid, ppv);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ULONG WINAPI InternetProtocol_AddRef(IInternetProtocol *iface)
|
||||||
|
{
|
||||||
|
MimeHtmlProtocol *This = impl_from_IInternetProtocol(iface);
|
||||||
|
return IUnknown_AddRef(This->outer_unk);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ULONG WINAPI InternetProtocol_Release(IInternetProtocol *iface)
|
||||||
|
{
|
||||||
|
MimeHtmlProtocol *This = impl_from_IInternetProtocol(iface);
|
||||||
|
return IUnknown_Release(This->outer_unk);
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI MimeHtmlProtocol_Start(IInternetProtocol *iface, const WCHAR *szUrl,
|
||||||
|
IInternetProtocolSink* pOIProtSink, IInternetBindInfo* pOIBindInfo,
|
||||||
|
DWORD grfPI, HANDLE_PTR dwReserved)
|
||||||
|
{
|
||||||
|
MimeHtmlProtocol *This = impl_from_IInternetProtocol(iface);
|
||||||
|
BINDINFO bindinfo = { sizeof(bindinfo) };
|
||||||
|
MimeHtmlBinding *binding;
|
||||||
|
IBindCtx *bind_ctx;
|
||||||
|
IStream *stream;
|
||||||
|
mhtml_url_t url;
|
||||||
|
DWORD bindf = 0;
|
||||||
|
IMoniker *mon;
|
||||||
|
HRESULT hres;
|
||||||
|
|
||||||
|
TRACE("(%p)->(%s %p %p %08x %lx)\n", This, debugstr_w(szUrl), pOIProtSink, pOIBindInfo, grfPI, dwReserved);
|
||||||
|
|
||||||
|
hres = parse_mhtml_url(szUrl, &url);
|
||||||
|
if(FAILED(hres))
|
||||||
|
return hres;
|
||||||
|
|
||||||
|
if(url.location && !(This->location = heap_strdupW(url.location)))
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
|
hres = IInternetBindInfo_GetBindInfo(pOIBindInfo, &bindf, &bindinfo);
|
||||||
|
if(FAILED(hres)) {
|
||||||
|
WARN("GetBindInfo failed: %08x\n", hres);
|
||||||
|
return hres;
|
||||||
|
}
|
||||||
|
if((bindf & (BINDF_ASYNCHRONOUS|BINDF_FROMURLMON|BINDF_NEEDFILE)) != (BINDF_ASYNCHRONOUS|BINDF_FROMURLMON|BINDF_NEEDFILE))
|
||||||
|
FIXME("unsupported bindf %x\n", bindf);
|
||||||
|
|
||||||
|
This->sink = pOIProtSink;
|
||||||
|
IInternetProtocolSink_AddRef(This->sink);
|
||||||
|
|
||||||
|
binding = heap_alloc(FIELD_OFFSET(MimeHtmlBinding, url[url.mhtml_len+1]));
|
||||||
|
if(!binding)
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
memcpy(binding->url, url.mhtml, url.mhtml_len*sizeof(WCHAR));
|
||||||
|
binding->url[url.mhtml_len] = 0;
|
||||||
|
|
||||||
|
hres = CreateURLMoniker(NULL, binding->url, &mon);
|
||||||
|
if(FAILED(hres))
|
||||||
|
return hres;
|
||||||
|
|
||||||
|
binding->IBindStatusCallback_iface.lpVtbl = &BindStatusCallbackVtbl;
|
||||||
|
binding->ref = 1;
|
||||||
|
binding->status = E_PENDING;
|
||||||
|
binding->stream = NULL;
|
||||||
|
binding->protocol = NULL;
|
||||||
|
|
||||||
|
hres = CreateAsyncBindCtx(0, &binding->IBindStatusCallback_iface, NULL, &bind_ctx);
|
||||||
|
if(FAILED(hres)) {
|
||||||
|
IMoniker_Release(mon);
|
||||||
|
IBindStatusCallback_Release(&binding->IBindStatusCallback_iface);
|
||||||
|
return hres;
|
||||||
|
}
|
||||||
|
|
||||||
|
IInternetProtocol_AddRef(&This->IInternetProtocol_iface);
|
||||||
|
binding->protocol = This;
|
||||||
|
|
||||||
|
hres = IMoniker_BindToStorage(mon, bind_ctx, NULL, &IID_IStream, (void**)&stream);
|
||||||
|
IBindCtx_Release(bind_ctx);
|
||||||
|
IMoniker_Release(mon);
|
||||||
|
if(stream)
|
||||||
|
IStream_Release(stream);
|
||||||
|
hres = binding->status;
|
||||||
|
IBindStatusCallback_Release(&binding->IBindStatusCallback_iface);
|
||||||
|
if(FAILED(hres) && hres != E_PENDING)
|
||||||
|
report_result(This, hres);
|
||||||
|
return hres;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI MimeHtmlProtocol_Continue(IInternetProtocol *iface, PROTOCOLDATA *pProtocolData)
|
||||||
|
{
|
||||||
|
MimeHtmlProtocol *This = impl_from_IInternetProtocol(iface);
|
||||||
|
FIXME("(%p)->(%p)\n", This, pProtocolData);
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI MimeHtmlProtocol_Abort(IInternetProtocol *iface, HRESULT hrReason, DWORD dwOptions)
|
||||||
|
{
|
||||||
|
MimeHtmlProtocol *This = impl_from_IInternetProtocol(iface);
|
||||||
|
FIXME("(%p)->(%08x %08x)\n", This, hrReason, dwOptions);
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI MimeHtmlProtocol_Terminate(IInternetProtocol *iface, DWORD dwOptions)
|
||||||
|
{
|
||||||
|
MimeHtmlProtocol *This = impl_from_IInternetProtocol(iface);
|
||||||
|
TRACE("(%p)->(%08x)\n", This, dwOptions);
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI MimeHtmlProtocol_Suspend(IInternetProtocol *iface)
|
||||||
|
{
|
||||||
|
MimeHtmlProtocol *This = impl_from_IInternetProtocol(iface);
|
||||||
|
FIXME("(%p)\n", This);
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI MimeHtmlProtocol_Resume(IInternetProtocol *iface)
|
||||||
|
{
|
||||||
|
MimeHtmlProtocol *This = impl_from_IInternetProtocol(iface);
|
||||||
|
FIXME("(%p)\n", This);
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI MimeHtmlProtocol_Read(IInternetProtocol *iface, void* pv, ULONG cb, ULONG* pcbRead)
|
||||||
|
{
|
||||||
|
MimeHtmlProtocol *This = impl_from_IInternetProtocol(iface);
|
||||||
|
ULONG read = 0;
|
||||||
|
HRESULT hres;
|
||||||
|
|
||||||
|
TRACE("(%p)->(%p %u %p)\n", This, pv, cb, pcbRead);
|
||||||
|
|
||||||
|
hres = IStream_Read(This->stream, pv, cb, &read);
|
||||||
|
if(pcbRead)
|
||||||
|
*pcbRead = read;
|
||||||
|
if(hres != S_OK)
|
||||||
|
return hres;
|
||||||
|
|
||||||
|
return read ? S_OK : S_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI MimeHtmlProtocol_Seek(IInternetProtocol *iface, LARGE_INTEGER dlibMove,
|
||||||
|
DWORD dwOrigin, ULARGE_INTEGER* plibNewPosition)
|
||||||
|
{
|
||||||
|
MimeHtmlProtocol *This = impl_from_IInternetProtocol(iface);
|
||||||
|
FIXME("(%p)->(%d %d %p)\n", This, dlibMove.u.LowPart, dwOrigin, plibNewPosition);
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI MimeHtmlProtocol_LockRequest(IInternetProtocol *iface, DWORD dwOptions)
|
||||||
|
{
|
||||||
|
MimeHtmlProtocol *This = impl_from_IInternetProtocol(iface);
|
||||||
|
FIXME("(%p)->(%d)\n", This, dwOptions);
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI MimeHtmlProtocol_UnlockRequest(IInternetProtocol *iface)
|
||||||
|
{
|
||||||
|
MimeHtmlProtocol *This = impl_from_IInternetProtocol(iface);
|
||||||
|
FIXME("(%p)\n", This);
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const IInternetProtocolVtbl MimeHtmlProtocolVtbl = {
|
||||||
|
InternetProtocol_QueryInterface,
|
||||||
|
InternetProtocol_AddRef,
|
||||||
|
InternetProtocol_Release,
|
||||||
|
MimeHtmlProtocol_Start,
|
||||||
|
MimeHtmlProtocol_Continue,
|
||||||
|
MimeHtmlProtocol_Abort,
|
||||||
|
MimeHtmlProtocol_Terminate,
|
||||||
|
MimeHtmlProtocol_Suspend,
|
||||||
|
MimeHtmlProtocol_Resume,
|
||||||
|
MimeHtmlProtocol_Read,
|
||||||
|
MimeHtmlProtocol_Seek,
|
||||||
|
MimeHtmlProtocol_LockRequest,
|
||||||
|
MimeHtmlProtocol_UnlockRequest
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline MimeHtmlProtocol *impl_from_IInternetProtocolInfo(IInternetProtocolInfo *iface)
|
||||||
|
{
|
||||||
|
return CONTAINING_RECORD(iface, MimeHtmlProtocol, IInternetProtocolInfo_iface);
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI MimeHtmlProtocolInfo_QueryInterface(IInternetProtocolInfo *iface, REFIID riid, void **ppv)
|
||||||
|
{
|
||||||
|
MimeHtmlProtocol *This = impl_from_IInternetProtocolInfo(iface);
|
||||||
|
return IUnknown_QueryInterface(This->outer_unk, riid, ppv);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ULONG WINAPI MimeHtmlProtocolInfo_AddRef(IInternetProtocolInfo *iface)
|
||||||
|
{
|
||||||
|
MimeHtmlProtocol *This = impl_from_IInternetProtocolInfo(iface);
|
||||||
|
return IUnknown_AddRef(This->outer_unk);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ULONG WINAPI MimeHtmlProtocolInfo_Release(IInternetProtocolInfo *iface)
|
||||||
|
{
|
||||||
|
MimeHtmlProtocol *This = impl_from_IInternetProtocolInfo(iface);
|
||||||
|
return IUnknown_Release(This->outer_unk);
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI MimeHtmlProtocolInfo_ParseUrl(IInternetProtocolInfo *iface, LPCWSTR pwzUrl,
|
||||||
|
PARSEACTION ParseAction, DWORD dwParseFlags, LPWSTR pwzResult, DWORD cchResult,
|
||||||
|
DWORD* pcchResult, DWORD dwReserved)
|
||||||
|
{
|
||||||
|
MimeHtmlProtocol *This = impl_from_IInternetProtocolInfo(iface);
|
||||||
|
FIXME("(%p)->(%s %d %x %p %d %p %d)\n", This, debugstr_w(pwzUrl), ParseAction,
|
||||||
|
dwParseFlags, pwzResult, cchResult, pcchResult, dwReserved);
|
||||||
|
return INET_E_DEFAULT_ACTION;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI MimeHtmlProtocolInfo_CombineUrl(IInternetProtocolInfo *iface,
|
||||||
|
LPCWSTR pwzBaseUrl, LPCWSTR pwzRelativeUrl, DWORD dwCombineFlags, LPWSTR pwzResult,
|
||||||
|
DWORD cchResult, DWORD* pcchResult, DWORD dwReserved)
|
||||||
|
{
|
||||||
|
MimeHtmlProtocol *This = impl_from_IInternetProtocolInfo(iface);
|
||||||
|
size_t len = sizeof(mhtml_prefixW)/sizeof(WCHAR);
|
||||||
|
mhtml_url_t url;
|
||||||
|
WCHAR *p;
|
||||||
|
HRESULT hres;
|
||||||
|
|
||||||
|
TRACE("(%p)->(%s %s %08x %p %d %p %d)\n", This, debugstr_w(pwzBaseUrl),
|
||||||
|
debugstr_w(pwzRelativeUrl), dwCombineFlags, pwzResult, cchResult,
|
||||||
|
pcchResult, dwReserved);
|
||||||
|
|
||||||
|
hres = parse_mhtml_url(pwzBaseUrl, &url);
|
||||||
|
if(FAILED(hres))
|
||||||
|
return hres;
|
||||||
|
|
||||||
|
if(!strncmpiW(pwzRelativeUrl, mhtml_prefixW, sizeof(mhtml_prefixW)/sizeof(WCHAR))) {
|
||||||
|
FIXME("Relative URL is mhtml protocol\n");
|
||||||
|
return INET_E_USE_DEFAULT_PROTOCOLHANDLER;
|
||||||
|
}
|
||||||
|
|
||||||
|
len += url.mhtml_len;
|
||||||
|
if(*pwzRelativeUrl)
|
||||||
|
len += strlenW(pwzRelativeUrl) + sizeof(mhtml_separatorW)/sizeof(WCHAR);
|
||||||
|
if(len >= cchResult) {
|
||||||
|
*pcchResult = 0;
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(pwzResult, mhtml_prefixW, sizeof(mhtml_prefixW));
|
||||||
|
p = pwzResult + sizeof(mhtml_prefixW)/sizeof(WCHAR);
|
||||||
|
memcpy(p, url.mhtml, url.mhtml_len*sizeof(WCHAR));
|
||||||
|
p += url.mhtml_len;
|
||||||
|
if(*pwzRelativeUrl) {
|
||||||
|
memcpy(p, mhtml_separatorW, sizeof(mhtml_separatorW));
|
||||||
|
p += sizeof(mhtml_separatorW)/sizeof(WCHAR);
|
||||||
|
strcpyW(p, pwzRelativeUrl);
|
||||||
|
}else {
|
||||||
|
*p = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
*pcchResult = len;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI MimeHtmlProtocolInfo_CompareUrl(IInternetProtocolInfo *iface, LPCWSTR pwzUrl1,
|
||||||
|
LPCWSTR pwzUrl2, DWORD dwCompareFlags)
|
||||||
|
{
|
||||||
|
MimeHtmlProtocol *This = impl_from_IInternetProtocolInfo(iface);
|
||||||
|
FIXME("(%p)->(%s %s %08x)\n", This, debugstr_w(pwzUrl1), debugstr_w(pwzUrl2), dwCompareFlags);
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI MimeHtmlProtocolInfo_QueryInfo(IInternetProtocolInfo *iface, LPCWSTR pwzUrl,
|
||||||
|
QUERYOPTION QueryOption, DWORD dwQueryFlags, LPVOID pBuffer, DWORD cbBuffer, DWORD* pcbBuf,
|
||||||
|
DWORD dwReserved)
|
||||||
|
{
|
||||||
|
MimeHtmlProtocol *This = impl_from_IInternetProtocolInfo(iface);
|
||||||
|
FIXME("(%p)->(%s %08x %08x %p %d %p %d)\n", This, debugstr_w(pwzUrl), QueryOption, dwQueryFlags, pBuffer,
|
||||||
|
cbBuffer, pcbBuf, dwReserved);
|
||||||
|
return INET_E_USE_DEFAULT_PROTOCOLHANDLER;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const IInternetProtocolInfoVtbl MimeHtmlProtocolInfoVtbl = {
|
||||||
|
MimeHtmlProtocolInfo_QueryInterface,
|
||||||
|
MimeHtmlProtocolInfo_AddRef,
|
||||||
|
MimeHtmlProtocolInfo_Release,
|
||||||
|
MimeHtmlProtocolInfo_ParseUrl,
|
||||||
|
MimeHtmlProtocolInfo_CombineUrl,
|
||||||
|
MimeHtmlProtocolInfo_CompareUrl,
|
||||||
|
MimeHtmlProtocolInfo_QueryInfo
|
||||||
|
};
|
||||||
|
|
||||||
|
HRESULT MimeHtmlProtocol_create(IUnknown *outer, void **obj)
|
||||||
|
{
|
||||||
|
MimeHtmlProtocol *protocol;
|
||||||
|
|
||||||
|
protocol = heap_alloc(sizeof(*protocol));
|
||||||
|
if(!protocol)
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
|
protocol->IUnknown_inner.lpVtbl = &MimeHtmlProtocolInnerVtbl;
|
||||||
|
protocol->IInternetProtocol_iface.lpVtbl = &MimeHtmlProtocolVtbl;
|
||||||
|
protocol->IInternetProtocolInfo_iface.lpVtbl = &MimeHtmlProtocolInfoVtbl;
|
||||||
|
protocol->ref = 1;
|
||||||
|
protocol->outer_unk = outer ? outer : &protocol->IUnknown_inner;
|
||||||
|
protocol->location = NULL;
|
||||||
|
protocol->stream = NULL;
|
||||||
|
protocol->sink = NULL;
|
||||||
|
|
||||||
|
*obj = &protocol->IUnknown_inner;
|
||||||
|
return S_OK;
|
||||||
|
}
|
|
@ -78,7 +78,7 @@ reactos/dll/win32/ieframe # Synced to WineStaging-2.2
|
||||||
reactos/dll/win32/imaadp32.acm # Synced to WineStaging-2.2
|
reactos/dll/win32/imaadp32.acm # Synced to WineStaging-2.2
|
||||||
reactos/dll/win32/imagehlp # Synced to WineStaging-1.9.11
|
reactos/dll/win32/imagehlp # Synced to WineStaging-1.9.11
|
||||||
reactos/dll/win32/imm32 # Synced to Wine-1.7.27
|
reactos/dll/win32/imm32 # Synced to Wine-1.7.27
|
||||||
reactos/dll/win32/inetcomm # Synced to WineStaging-1.9.23
|
reactos/dll/win32/inetcomm # Synced to WineStaging-2.2
|
||||||
reactos/dll/win32/inetmib1 # Synced to WineStaging-1.9.11
|
reactos/dll/win32/inetmib1 # Synced to WineStaging-1.9.11
|
||||||
reactos/dll/win32/initpki # Synced to WineStaging-1.9.11
|
reactos/dll/win32/initpki # Synced to WineStaging-1.9.11
|
||||||
reactos/dll/win32/inseng # Synced to WineStaging-2.2
|
reactos/dll/win32/inseng # Synced to WineStaging-2.2
|
||||||
|
|
Loading…
Reference in a new issue