Added about protocol implementation.
This commit is contained in:
parent
db5b331f3a
commit
f193c26554
|
@ -138,7 +138,12 @@ static HRESULT WINAPI ClassFactory_LockServer(IClassFactory *iface, BOOL dolock)
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
const IInternetProtocolVtbl *lpInternetProtocolVtbl;
|
const IInternetProtocolVtbl *lpInternetProtocolVtbl;
|
||||||
|
|
||||||
LONG ref;
|
LONG ref;
|
||||||
|
|
||||||
|
BYTE *data;
|
||||||
|
ULONG data_len;
|
||||||
|
ULONG cur;
|
||||||
} AboutProtocol;
|
} AboutProtocol;
|
||||||
|
|
||||||
static HRESULT WINAPI AboutProtocol_QueryInterface(IInternetProtocol *iface, REFIID riid, void **ppv)
|
static HRESULT WINAPI AboutProtocol_QueryInterface(IInternetProtocol *iface, REFIID riid, void **ppv)
|
||||||
|
@ -184,6 +189,7 @@ static ULONG WINAPI AboutProtocol_Release(IInternetProtocol *iface)
|
||||||
TRACE("(%p) ref=%lx\n", iface, ref);
|
TRACE("(%p) ref=%lx\n", iface, ref);
|
||||||
|
|
||||||
if(!ref) {
|
if(!ref) {
|
||||||
|
HeapFree(GetProcessHeap(), 0, This->data);
|
||||||
HeapFree(GetProcessHeap(), 0, This);
|
HeapFree(GetProcessHeap(), 0, This);
|
||||||
UNLOCK_MODULE();
|
UNLOCK_MODULE();
|
||||||
}
|
}
|
||||||
|
@ -196,9 +202,53 @@ static HRESULT WINAPI AboutProtocol_Start(IInternetProtocol *iface, LPCWSTR szUr
|
||||||
DWORD grfPI, DWORD dwReserved)
|
DWORD grfPI, DWORD dwReserved)
|
||||||
{
|
{
|
||||||
AboutProtocol *This = (AboutProtocol*)iface;
|
AboutProtocol *This = (AboutProtocol*)iface;
|
||||||
FIXME("(%p)->(%s %p %p %08lx %ld)\n", This, debugstr_w(szUrl), pOIProtSink,
|
BINDINFO bindinfo;
|
||||||
|
DWORD grfBINDF = 0;
|
||||||
|
LPCWSTR text = NULL;
|
||||||
|
|
||||||
|
static const WCHAR html_begin[] = {0xfeff,'<','H','T','M','L','>',0};
|
||||||
|
static const WCHAR html_end[] = {'<','/','H','T','M','L','>',0};
|
||||||
|
static const WCHAR wszBlank[] = {'b','l','a','n','k',0};
|
||||||
|
static const WCHAR wszAbout[] = {'a','b','o','u','t',':'};
|
||||||
|
|
||||||
|
/* NOTE:
|
||||||
|
* the about protocol seems not to work as I would expect. It creates html document
|
||||||
|
* for a given url, eg. about:some_text -> <HTML>some_text</HTML> except for the case when
|
||||||
|
* some_text = "blank", when document is blank (<HTML></HMTL>). The same happens
|
||||||
|
* when the url does not have "about:" in the beginning.
|
||||||
|
*/
|
||||||
|
|
||||||
|
TRACE("(%p)->(%s %p %p %08lx %ld)\n", This, debugstr_w(szUrl), pOIProtSink,
|
||||||
pOIBindInfo, grfPI, dwReserved);
|
pOIBindInfo, grfPI, dwReserved);
|
||||||
return E_NOTIMPL;
|
|
||||||
|
memset(&bindinfo, 0, sizeof(bindinfo));
|
||||||
|
bindinfo.cbSize = sizeof(BINDINFO);
|
||||||
|
IInternetBindInfo_GetBindInfo(pOIBindInfo, &grfBINDF, &bindinfo);
|
||||||
|
|
||||||
|
if(strlenW(szUrl)>=sizeof(wszAbout)/sizeof(WCHAR) && !memcmp(wszAbout, szUrl, sizeof(wszAbout))) {
|
||||||
|
text = szUrl + sizeof(wszAbout)/sizeof(WCHAR);
|
||||||
|
if(!strcmpW(wszBlank, text))
|
||||||
|
text = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
This->data_len = sizeof(html_begin)+sizeof(html_end)-sizeof(WCHAR)
|
||||||
|
+ (text ? strlenW(text)*sizeof(WCHAR) : 0);
|
||||||
|
This->data = HeapAlloc(GetProcessHeap(), 0, This->data_len);
|
||||||
|
|
||||||
|
memcpy(This->data, html_begin, sizeof(html_begin));
|
||||||
|
if(text)
|
||||||
|
strcatW((LPWSTR)This->data, text);
|
||||||
|
strcatW((LPWSTR)This->data, html_end);
|
||||||
|
|
||||||
|
This->cur = 0;
|
||||||
|
|
||||||
|
IInternetProtocolSink_ReportData(pOIProtSink,
|
||||||
|
BSCF_FIRSTDATANOTIFICATION | BSCF_LASTDATANOTIFICATION | BSCF_DATAFULLYAVAILABLE,
|
||||||
|
This->data_len, This->data_len);
|
||||||
|
|
||||||
|
IInternetProtocolSink_ReportResult(pOIProtSink, S_OK, 0, NULL);
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI AboutProtocol_Continue(IInternetProtocol *iface, PROTOCOLDATA* pProtocolData)
|
static HRESULT WINAPI AboutProtocol_Continue(IInternetProtocol *iface, PROTOCOLDATA* pProtocolData)
|
||||||
|
@ -219,8 +269,8 @@ static HRESULT WINAPI AboutProtocol_Abort(IInternetProtocol *iface, HRESULT hrRe
|
||||||
static HRESULT WINAPI AboutProtocol_Terminate(IInternetProtocol *iface, DWORD dwOptions)
|
static HRESULT WINAPI AboutProtocol_Terminate(IInternetProtocol *iface, DWORD dwOptions)
|
||||||
{
|
{
|
||||||
AboutProtocol *This = (AboutProtocol*)iface;
|
AboutProtocol *This = (AboutProtocol*)iface;
|
||||||
FIXME("(%p)->(%08lx)\n", This, dwOptions);
|
TRACE("(%p)->(%08lx)\n", This, dwOptions);
|
||||||
return E_NOTIMPL;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI AboutProtocol_Suspend(IInternetProtocol *iface)
|
static HRESULT WINAPI AboutProtocol_Suspend(IInternetProtocol *iface)
|
||||||
|
@ -240,8 +290,21 @@ static HRESULT WINAPI AboutProtocol_Resume(IInternetProtocol *iface)
|
||||||
static HRESULT WINAPI AboutProtocol_Read(IInternetProtocol *iface, void* pv, ULONG cb, ULONG* pcbRead)
|
static HRESULT WINAPI AboutProtocol_Read(IInternetProtocol *iface, void* pv, ULONG cb, ULONG* pcbRead)
|
||||||
{
|
{
|
||||||
AboutProtocol *This = (AboutProtocol*)iface;
|
AboutProtocol *This = (AboutProtocol*)iface;
|
||||||
FIXME("(%p)->(%lu %p)\n", This, cb, pcbRead);
|
|
||||||
return E_NOTIMPL;
|
TRACE("(%p)->(%p %lu %p)\n", This, pv, cb, pcbRead);
|
||||||
|
|
||||||
|
if(!This->data)
|
||||||
|
return E_FAIL;
|
||||||
|
|
||||||
|
*pcbRead = (cb > This->data_len-This->cur ? This->data_len-This->cur : cb);
|
||||||
|
|
||||||
|
if(!*pcbRead)
|
||||||
|
return S_FALSE;
|
||||||
|
|
||||||
|
memcpy(pv, This->data, *pcbRead);
|
||||||
|
This->cur += *pcbRead;
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI AboutProtocol_Seek(IInternetProtocol *iface, LARGE_INTEGER dlibMove,
|
static HRESULT WINAPI AboutProtocol_Seek(IInternetProtocol *iface, LARGE_INTEGER dlibMove,
|
||||||
|
@ -255,15 +318,19 @@ static HRESULT WINAPI AboutProtocol_Seek(IInternetProtocol *iface, LARGE_INTEGER
|
||||||
static HRESULT WINAPI AboutProtocol_LockRequest(IInternetProtocol *iface, DWORD dwOptions)
|
static HRESULT WINAPI AboutProtocol_LockRequest(IInternetProtocol *iface, DWORD dwOptions)
|
||||||
{
|
{
|
||||||
AboutProtocol *This = (AboutProtocol*)iface;
|
AboutProtocol *This = (AboutProtocol*)iface;
|
||||||
FIXME("(%p)->(%ld)\n", This, dwOptions);
|
|
||||||
return E_NOTIMPL;
|
TRACE("(%p)->(%ld)\n", This, dwOptions);
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI AboutProtocol_UnlockRequest(IInternetProtocol *iface)
|
static HRESULT WINAPI AboutProtocol_UnlockRequest(IInternetProtocol *iface)
|
||||||
{
|
{
|
||||||
AboutProtocol *This = (AboutProtocol*)iface;
|
AboutProtocol *This = (AboutProtocol*)iface;
|
||||||
FIXME("(%p)\n", This);
|
|
||||||
return E_NOTIMPL;
|
TRACE("(%p)\n", This);
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const IInternetProtocolVtbl AboutProtocolVtbl = {
|
static const IInternetProtocolVtbl AboutProtocolVtbl = {
|
||||||
|
@ -294,6 +361,10 @@ static HRESULT WINAPI AboutProtocolFactory_CreateInstance(IClassFactory *iface,
|
||||||
ret->lpInternetProtocolVtbl = &AboutProtocolVtbl;
|
ret->lpInternetProtocolVtbl = &AboutProtocolVtbl;
|
||||||
ret->ref = 0;
|
ret->ref = 0;
|
||||||
|
|
||||||
|
ret->data = NULL;
|
||||||
|
ret->data_len = 0;
|
||||||
|
ret->cur = 0;
|
||||||
|
|
||||||
hres = IUnknown_QueryInterface((IUnknown*)ret, riid, ppv);
|
hres = IUnknown_QueryInterface((IUnknown*)ret, riid, ppv);
|
||||||
|
|
||||||
if(SUCCEEDED(hres))
|
if(SUCCEEDED(hres))
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#include "initguid.h"
|
#include "initguid.h"
|
||||||
|
|
||||||
DEFINE_GUID(CLSID_ResProtocol, 0x3050F3BC, 0x98B5, 0x11CF, 0xBB,0x82, 0x00,0xAA,0x00,0xBD,0xCE,0x0B);
|
DEFINE_GUID(CLSID_ResProtocol, 0x3050F3BC, 0x98B5, 0x11CF, 0xBB,0x82, 0x00,0xAA,0x00,0xBD,0xCE,0x0B);
|
||||||
|
DEFINE_GUID(CLSID_AboutProtocol, 0x3050F406, 0x98B5, 0x11CF, 0xBB,0x82, 0x00,0xAA,0x00,0xBD,0xCE,0x0B);
|
||||||
|
|
||||||
static BOOL expect_GetBindInfo = FALSE, called_GetBindInfo = FALSE;
|
static BOOL expect_GetBindInfo = FALSE, called_GetBindInfo = FALSE;
|
||||||
static BOOL expect_ReportProgress = FALSE, called_ReportProgress = FALSE;
|
static BOOL expect_ReportProgress = FALSE, called_ReportProgress = FALSE;
|
||||||
|
@ -312,6 +313,83 @@ static void test_res_protocol(void)
|
||||||
protocol_start(protocol, blank_url);
|
protocol_start(protocol, blank_url);
|
||||||
hres = IInternetProtocol_Read(protocol, buf, sizeof(buf), &cb);
|
hres = IInternetProtocol_Read(protocol, buf, sizeof(buf), &cb);
|
||||||
ok(hres == S_OK, "Read failed: %08lx\n", hres);
|
ok(hres == S_OK, "Read failed: %08lx\n", hres);
|
||||||
|
hres = IInternetProtocol_Terminate(protocol, 0);
|
||||||
|
ok(hres == S_OK, "Terminate failed: %08lx\n", hres);
|
||||||
|
|
||||||
|
IInternetProtocol_Release(protocol);
|
||||||
|
}
|
||||||
|
|
||||||
|
IClassFactory_Release(factory);
|
||||||
|
}
|
||||||
|
|
||||||
|
IUnknown_Release(unk);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_about_protocol(void)
|
||||||
|
{
|
||||||
|
IInternetProtocolInfo *protocol_info;
|
||||||
|
IUnknown *unk;
|
||||||
|
IClassFactory *factory;
|
||||||
|
HRESULT hres;
|
||||||
|
|
||||||
|
static const WCHAR blank_url[] = {'a','b','o','u','t',':','b','l','a','n','k',0};
|
||||||
|
static const WCHAR test_url[] = {'a','b','o','u','t',':','t','e','s','t',0};
|
||||||
|
static const WCHAR res_url[] = {'r','e','s',':','b','l','a','n','k',0};
|
||||||
|
static const WCHAR blank_html[] = {0xfeff,'<','H','T','M','L','>','<','/','H','T','M','L','>',0};
|
||||||
|
static const WCHAR test_html[] =
|
||||||
|
{0xfeff,'<','H','T','M','L','>','t','e','s','t','<','/','H','T','M','L','>',0};
|
||||||
|
|
||||||
|
hres = CoGetClassObject(&CLSID_AboutProtocol, CLSCTX_INPROC_SERVER, NULL, &IID_IUnknown, (void**)&unk);
|
||||||
|
ok(hres == S_OK, "CoGetClassObject failed: %08lx\n", hres);
|
||||||
|
if(!SUCCEEDED(hres))
|
||||||
|
return;
|
||||||
|
|
||||||
|
hres = IUnknown_QueryInterface(unk, &IID_IInternetProtocolInfo, (void**)&protocol_info);
|
||||||
|
ok(hres == S_OK, "Could not get IInternetProtocolInfo interface: %08lx\n", hres);
|
||||||
|
if(SUCCEEDED(hres)) {
|
||||||
|
/* TODO: test IInternetProtocol interface */
|
||||||
|
IInternetProtocol_Release(protocol_info);
|
||||||
|
}
|
||||||
|
|
||||||
|
hres = IUnknown_QueryInterface(unk, &IID_IClassFactory, (void**)&factory);
|
||||||
|
ok(hres == S_OK, "Could not get IClassFactory interface\n");
|
||||||
|
if(SUCCEEDED(hres)) {
|
||||||
|
IInternetProtocol *protocol;
|
||||||
|
BYTE buf[512];
|
||||||
|
ULONG cb;
|
||||||
|
hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol, (void**)&protocol);
|
||||||
|
ok(hres == S_OK, "Could not get IInternetProtocol: %08lx\n", hres);
|
||||||
|
|
||||||
|
if(SUCCEEDED(hres)) {
|
||||||
|
protocol_start(protocol, blank_url);
|
||||||
|
hres = IInternetProtocol_LockRequest(protocol, 0);
|
||||||
|
ok(hres == S_OK, "LockRequest failed: %08lx\n", hres);
|
||||||
|
hres = IInternetProtocol_Read(protocol, buf, sizeof(buf), &cb);
|
||||||
|
ok(hres == S_OK, "Read failed: %08lx\n", hres);
|
||||||
|
ok(cb == sizeof(blank_html), "cb=%ld, expected %d\n", cb, sizeof(blank_html));
|
||||||
|
ok(!memcmp(buf, blank_html, cb), "Readed wrong data\n");
|
||||||
|
hres = IInternetProtocol_UnlockRequest(protocol);
|
||||||
|
ok(hres == S_OK, "UnlockRequest failed: %08lx\n", hres);
|
||||||
|
|
||||||
|
protocol_start(protocol, test_url);
|
||||||
|
hres = IInternetProtocol_LockRequest(protocol, 0);
|
||||||
|
ok(hres == S_OK, "LockRequest failed: %08lx\n", hres);
|
||||||
|
hres = IInternetProtocol_Read(protocol, buf, sizeof(buf), &cb);
|
||||||
|
ok(hres == S_OK, "Read failed: %08lx\n", hres);
|
||||||
|
ok(cb == sizeof(test_html), "cb=%ld, expected %d\n", cb, sizeof(test_html));
|
||||||
|
ok(!memcmp(buf, test_html, cb), "Readed wrong data\n");
|
||||||
|
hres = IInternetProtocol_UnlockRequest(protocol);
|
||||||
|
ok(hres == S_OK, "UnlockRequest failed: %08lx\n", hres);
|
||||||
|
|
||||||
|
protocol_start(protocol, res_url);
|
||||||
|
hres = IInternetProtocol_LockRequest(protocol, 0);
|
||||||
|
ok(hres == S_OK, "LockRequest failed: %08lx\n", hres);
|
||||||
|
hres = IInternetProtocol_Read(protocol, buf, sizeof(buf), &cb);
|
||||||
|
ok(hres == S_OK, "Read failed: %08lx\n", hres);
|
||||||
|
ok(cb == sizeof(blank_html), "cb=%ld, expected %d\n", cb, sizeof(blank_html));
|
||||||
|
ok(!memcmp(buf, blank_html, cb), "Readed wrong data\n");
|
||||||
|
hres = IInternetProtocol_UnlockRequest(protocol);
|
||||||
|
ok(hres == S_OK, "UnlockRequest failed: %08lx\n", hres);
|
||||||
|
|
||||||
IInternetProtocol_Release(protocol);
|
IInternetProtocol_Release(protocol);
|
||||||
}
|
}
|
||||||
|
@ -327,6 +405,7 @@ START_TEST(protocol)
|
||||||
OleInitialize(NULL);
|
OleInitialize(NULL);
|
||||||
|
|
||||||
test_res_protocol();
|
test_res_protocol();
|
||||||
|
test_about_protocol();
|
||||||
|
|
||||||
OleUninitialize();
|
OleUninitialize();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue